修复/规避:WhatsApp 消息在 OpenClaw 里变成 [object Object](sanitizeChatSendMessageInput)
OpenClaw News 编辑部
如果你用 WhatsApp(Baileys) 接入 OpenClaw,可能会遇到一种非常“像模型坏了”的现象:用户发来的文本,模型侧看到的却是 [object Object]。
这通常不是提示词问题,也不是模型理解能力问题,而是输入清洗阶段的类型假设被打破:某些情况下 WhatsApp 适配层把“消息对象”直接传进了字符串处理函数。
来源
- Issue 追踪: openclaw/openclaw#52464
现象特征
- 同一个环境里,有时消息正常,有时突然变成
[object Object]。 - 影响 DM 和群聊都可能发生。
- 一旦出现,agent 基本无法继续对话,因为它根本没拿到原始文本。
如果你把入站 payload 打出来,往往能看到:WhatsApp 侧传进来的不是纯字符串,而是 Baileys 的结构化消息对象(里面可能包含 conversation、extendedTextMessage 等字段)。
根因(为什么会变成 [object Object])
Issue 中定位到问题发生在 sanitizeChatSendMessageInput()。
这个函数默认 message 是字符串,并做了 Unicode 归一化:
message.normalize("NFC")
当 message 实际上是对象时,JavaScript 会发生隐式类型转换;对普通对象来说,最终会变成:
String({}) === "[object Object]"
于是 LLM 收到的“用户输入”就退化成了字面量 [object Object]。
如何确认你命中的就是这个问题
- 复现一次(或抓到一次线上样本)。
- 查看 gateway 日志/调试输出。
- 重点确认:进入聊天/会话层的
message是否曾经是 非字符串(object),随后才变成[object Object]。
只要确认了是对象从 WhatsApp 适配层漏出来,就不建议用“提示词绕过”。正确方向是:边界抽取文本 或 加类型守卫。
不改代码的缓解手段(能立刻降低损失)
- 提示用户重发一次
这类问题常常是“间歇性”,第二条消息可能就正常。
- 把
[object Object]当作异常输入处理
如果你的系统里有基于关键字触发的自动化(例如把特定文本当指令),建议明确忽略这条字面量,避免误触发。
- 留一份最小诊断样本
保留一条发生问题时的 Baileys 原始对象(注意脱敏:手机号、群ID等),后续才能写出稳定的“文本抽取规则”。
更稳妥的修复方向(推荐)
有两个修复点:
方案 A(更推荐):在 WhatsApp 适配层“先抽取文本,再入库/入模”
把 Baileys 的消息对象规范化为纯字符串:
- 普通文本:优先取
conversation - 扩展文本:取
extendedTextMessage.text - 其它类型(引用、媒体 caption 等):按 Baileys 结构分别取值
优点:不会把结构化对象内容意外拼进 prompt;输入更可控。
方案 B:在 sanitizeChatSendMessageInput() 里加类型守卫
Issue 建议的思路是:
- 发现
message不是 string 时,优先从对象里取text/body/conversation/... - 否则才回退到
String(message)
注意:把对象强转为字符串可能会把不该给模型看的元数据带进去(例如 id、时间戳)。如果可以修改适配层,优先走方案 A。
打补丁后要重点回归哪些场景
- Emoji / 非拉丁字符是否仍能正确 normalize
- 引用回复、媒体 caption、群聊消息这些字段路径是否一致
- 至少加三类测试样本:
conversationextendedTextMessage.text- caption
搜索入口补强:用户真正搜索的通常不是函数名
大多数运维同学不会搜索 sanitizeChatSendMessageInput,而是直接搜索眼前看到的症状,比如:
OpenClaw WhatsApp [object Object]WhatsApp 消息在 OpenClaw 里变成 [object Object]OpenClaw Baileys 把消息传成 object objectsanitizeChatSendMessageInput 收到 object 不是 stringOpenClaw WhatsApp 读不到用户文本
如果你是从这些搜索词点进来的,最快的判断顺序是:
- 如果只有 WhatsApp 受影响
- 这与本文讨论的适配层 / 清洗层问题高度吻合。
- 如果模型侧真的收到了字面量
[object Object]- 这就是最典型的对象被强转成字符串的症状。
- 如果所有渠道都一起坏了,不只是 WhatsApp
- 应先排查更广义的消息路由或会话输入链路,而不是直接锁定这一个 bug。
- 如果只影响媒体 caption、引用回复或特定消息形态
- 你仍可能命中同一类问题,只是要优先检查字段抽取路径。
这种“按症状走”的入口,通常比直接翻内部函数名更快。
哪些情况大概率不是这篇在说的问题
如果你遇到的是下面这些情况,这篇文章大概率不对症:
- 用户消息根本没有进入 OpenClaw
- WhatsApp 投递本身就在 OpenClaw 之前失败了
- 模型收到的是空字符串,但从来没出现过字面量
[object Object] - Telegram、Discord、Feishu 也都一模一样地被污染
这几类情况更应该先查传输、投递或更广义的输入链路,而不是直接假设命中了这个 WhatsApp 对象强转问题。
3 步运维摘要
如果你只有 2 分钟,优先按这个顺序排:
- 抓一条失败时的入站 WhatsApp 样本
- 确认
message在 sanitize 之前是否是对象 - 先在 WhatsApp 适配边界抽取文本,再考虑提示词侧绕过
如果第 2 步为“是”,你大概率命中的就是同一类问题。
如果抽取 conversation 或 extendedTextMessage.text 后问题消失,就应把适配层边界视为真正修复点。
追踪链接
- 上游 issue: openclaw/openclaw#52464
](/_next/image?url=%2Fimages%2Fnews%2Fcovers%2Ftutorial.png&w=1920&q=75)