绕了一上午,我才搞懂 OpenClaw 为什么不回我消息

📅 2026/7/31 9:42:01 👁️ 阅读次数 📝 编程学习
绕了一上午,我才搞懂 OpenClaw 为什么不回我消息

绕了一上午,我才搞懂 OpenClaw 为什么不回我消息

本文基于一次真实的端到端排障经历。涉及的 IP、端口、API Key、requestId 等敏感信息已脱敏替换为占位符。


一、0 故障爆发:AI 助手突然变成 AI 静默

“OpenClaw 用不了了。”

下午两点,钉钉群里有人@我。紧接着 Web 管理端、命令行,三个渠道同时传来消息——都是发出去没人回

直觉告诉我:这是大故障。但直觉这种东西,有时候是朋友,有时候是坑。

这次直觉是坑。

实际根因是四个小 bug 叠在一起:Web 端设备未配对 + 默认模型认证失败 + 上下文窗口过小 + 偶发限流。任何一个单拎出来都不致命,但叠在一起,就让 OpenClaw 看起来像"完全死了"。

我花了一整个上午去定位和修复,中间绕了不少路。这篇文章把整个过程还原出来——不仅讲怎么修,更讲我是怎么走偏的、走偏后怎么拉回来的。希望未来某天,你或者我自己在凌晨两点碰到类似情况,能省下两个小时。


二、第 1 误判:把"设备配对"当成"频道配对"

第一动作是查 Gateway 状态:

openclaw gateway status

进程存活,但Connectivity probe失败,状态是pairing-pending

“pairing-pending”——我第一反应是去查pairing命令。当时挺自信的:文档里说得很清楚,pairing就是处理未配对设备的。

openclaw pairing list,回我一句:

Channel required. Use --channel <channel>

我盯着屏幕看了三秒。

“Channel required”?我只是想列一下待配对设备,为什么要我指定频道?

那一刻我才反应过来——OpenClaw 内部把"设备"和"频道"当成两回事。

pairing是给消息频道(钉钉、Telegram)用的;Web 管理端是 WebSocket 连接,归devices管。命名差异很小,但语义边界很清楚。

切换到正确的命令:

openclaw devices list openclaw devices approve<request-id>

批准之后,Web 端立刻活了。Connectivity probepairing-pending变成ok

小小一个命名差异,让我绕了十分钟。


三、第 2 误判:以为只是临时抖动,其实是认证失败

钉钉那边还在报Something went wrong,或者更具体的(2064) 服务集群负载较高

我以为是临时抖动,等了五分钟。还在报错。又等了十分钟。还是不通。

翻日志。

openclaw logs--tail30

看到一行关键错误:

LLM error authentication_error: invalid api key auth or provider access failed for <provider-name>.

authentication_error?我明明配过 API Key,怎么会认证失败?

打开~/.openclaw/openclaw.json,一眼扫过去:两个 Provider

第一个,https://api.<official-domain>/anthropic没有apiKey字段——我之前用官方服务的时候配过,后来切到内网就把这块忘了,没删干净。

第二个,http://<内网IP>:<内网端口>/v1,apiKey 完整,baseUrl 正确。

我手动curl验证了一下内网服务:

curlhttp://<内网IP>:<内网端口>/v1/models\-H"Authorization: Bearer <api-key>"

返回正常模型列表——服务本身没问题

真相浮现:OpenClaw 启动时默认选中了第一个 Provider,也就是那个没配 key 的官方 Provider。第二个虽然能用,但系统压根没去问它。


四、绕路四十分钟:CLI、JSON、删 Provider

接下来发生的事情,现在回想起来都觉得有点打脸。

我花了大概四十分钟,跟 CLI 和 JSON 配置文件死磕。

尝试 1(CLI)

openclaw configsetmodels.defaultProvider"<provider-b-id>"# Config validation failed: models: Invalid input

→ 这个版本的 CLI不支持defaultProvider字段。

尝试 2(手动编辑 JSON):在models对象里手动加defaultProvider字段。

→ 重启 Gateway 直接报Invalid config,服务起不来。紧急回滚备份

尝试 3(删除无效 Provider A):编辑配置文件,把 Provider A 整个块删掉。

→ Gateway 起来了,但我也知道这操作太粗暴——万一以后想用官方服务就没了。

我甚至开始认真考虑:要不要自己改 OpenClaw 源码,把 defaultProvider 字段加进去

现在回头看,思路已经完全跑偏了。


五、✅ 转折:答案就在 Web UI 的下拉框里

就在我准备动手改源码的时候,眼睛扫过 Web 管理端的导航栏:

http://<gateway-host>:18789/openclaw/agents

点进去。Model Selection → Primary model (default),下拉框里清清楚楚列着所有可用的 Provider。我选了 Provider B,保存。

钉钉和 Web 端立刻就通了。

没有重启,没有改配置,没有动一行代码。

那一刻我有点想笑。绕了一大圈,最优解就在我每次打开都看过、但从来没点进去过的地方。

为什么这是最优解

  • Web UI 的模型选择是运行时配置,优先级高于配置文件默认值。
  • 多个 Provider 可以共存,显式指定即可避免冲突。
  • 零风险、实时生效、操作直观。
  • 万一选错,下拉框再切一次就行,比回滚备份安全多了。

这次教训是:工具的设计者早就把最安全的路径放在了离你最近的位置。绕远路,只是因为你太相信自己的第一直觉。


六、后续优化:上下文窗口与限流

主要故障修好之后,还有两个非关键问题顺手处理了。

6.1 上下文窗口过小

跑长对话时,OpenClaw 报错:

Auto-compaction could not recover this turn. Please use /new.

查了一下openclaw.json里 Provider B 的模型配置,contextWindow只配了 4000。短对话够用,长对话就会触发 compaction 失败。

应急/new清空会话。

永久修复:把contextWindowmaxTokens调大,并加上compaction.reserveTokensFloor

{"models":{"providers":[{"id":"<provider-b-id>","models":[{"name":"...","contextWindow":204800,"maxTokens":131072}]}]},"agents":{"defaults":{"compaction":{"reserveTokensFloor":20000}}}}

一个数字没配对,前面的所有努力都可能白费。

6.2 钉钉(2064)限流

钉钉偶尔返回(2064) 当前服务集群负载较高。这个错误很容易误判为"钉钉渠道故障"。

真相:是内网 AI 服务商的频率限制,跟 OpenClaw 和钉钉都没关系。

对策:稍后重试,或者联系服务商升级配额。


七、排查决策树(思维导图文字版)

故障现象:钉钉 / Web / CLI 均无回复 │ ├─ 第一步:基础状态检查 │ └─ openclaw gateway status → pairing-pending ? │ ├─ 是 → 设备未配对 │ │ └─ openclaw devices list → openclaw devices approve <request-id> │ └─ 否 → 进入第二步 │ ├─ 第二步:查看日志定位核心错误 │ └─ openclaw logs --tail 30 │ ├─ invalid api key / authentication_error → 模型认证失败 │ │ ├─ 🥇 优先:Web UI 切换 Provider(http://<host>:18789/openclaw/agents) │ │ ├─ 🥈 兜底:删除无效 Provider 或修正 apiKey │ │ └─ 🥉 最后:修改配置文件 + 重启 Gateway │ ├─ contextWindow / compaction → 上下文超长 │ │ └─ /new 清空;调大 contextWindow 和 reserveTokensFloor │ └─ blocked for inference → 账户受限 │ └─ 切换 Provider 或检查账户余额 │ ├─ 第三步:消息渠道单独不响应 │ ├─ Web 端不响应 → 检查 devices 配对 │ ├─ 钉钉不响应 → openclaw pairing list --channel dingtalk │ └─ CLI 不响应 → openclaw chat --provider <provider-b-id> │ └─ 第四步:偶发限流 (2064) └─ 稍后重试;联系 AI 服务商升级配额

八、标准操作流程(SOP)

按优先级排序,从最安全、最简单开始。

🥇 第一优先:Web UI 切换模型

适用场景:多 Provider 共存,其中一个无效,需要显式指定可用模型。

步骤

  1. 访问http://<gateway-host>:18789/openclaw/agents
  2. Model SelectionPrimary model (default)下拉框
  3. 选择可用的 Provider / 模型
  4. 保存 → 立即生效

为什么最优先:运行时配置覆盖默认值,零风险,无需重启 Gateway。

🥈 第二优先:处理配对 / 连接问题

连接类型查看待批准批准命令
Web 管理连接(WebSocket)openclaw devices listopenclaw devices approve <request-id>
消息频道(钉钉 / Telegram)openclaw pairing list --channel <channel>openclaw pairing approve --channel <channel> <user-id>

🥉 第三优先:日志定位

openclaw logs--tail30

常见错误关键词与对策

错误关键词原因对策
invalid api key/authentication_errorAPI Key 无效或未配置1. Web UI 切换 Provider
2. 更新配置文件apiKey
pairing-pending设备 / 用户未批准devices approvepairing approve
contextWindow/compaction上下文超长/new;调大contextWindowreserveTokensFloor
blocked for inference账户受限切换 Provider 或检查余额

第四优先:修改配置文件(最后手段)

操作前必做(备份)

cp~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak

修改后必做

openclaw config validate# 验证配置openclaw gateway restart# 重启生效

第五优先:处理钉钉限流(2064)

这是AI 服务商限流,不是 OpenClaw / 钉钉的问题。对策:等待 1-5 分钟后重试;降低并发;联系服务商升级配额。


九、关键经验教训

  1. Web UI 优先于 CLI— 多数配置(尤其是模型选择)可 Web 端覆盖,更安全、更快捷。
  2. Provider 可以共存— 多个 Provider 不会冲突,关键是显式指定可用的那个。
  3. 日志是灯塔openclaw logs --tail 30比任何猜测都有效,所有关键错误都会在日志中显现。
  4. 配对命令要分清devices管 Web 连接,pairing --channel管消息频道。
  5. 上下文管理是长期健康的关键— 对于支持大上下文的模型,务必调大contextWindowreserveTokensFloor,避免频繁出现 compaction 错误。
  6. (2064)不是钉钉的锅— 它是 AI 服务商限流的外显表现,不要误判为钉钉渠道故障。
  7. 最复杂的问题,答案有时就在最简单的地方— Web UI 的下拉选择,胜过 CLI 和 JSON。

踩过的坑,比读过的书更有价值。


十、本次故障最终状态

检查项状态
Gateway 运行状态running
Connectivity probeok
Web 端消息回复✅ 正常
钉钉消息回复✅ 正常
命令行openclaw chat✅ 正常
长对话上下文已调大阈值,稳定运行
钉钉(2064)限流偶发,稍后重试可恢复

我是magicCzc,一个把 AIOps 当信仰的运维开发工程师。
GitHub:https://github.com/magicCzc