绕了一上午,我才搞懂 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 probe从pairing-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清空会话。
永久修复:把contextWindow和maxTokens调大,并加上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 共存,其中一个无效,需要显式指定可用模型。
步骤:
- 访问
http://<gateway-host>:18789/openclaw/agents - Model Selection→Primary model (default)下拉框
- 选择可用的 Provider / 模型
- 保存 → 立即生效
为什么最优先:运行时配置覆盖默认值,零风险,无需重启 Gateway。
🥈 第二优先:处理配对 / 连接问题
| 连接类型 | 查看待批准 | 批准命令 |
|---|---|---|
| Web 管理连接(WebSocket) | openclaw devices list | openclaw devices approve <request-id> |
| 消息频道(钉钉 / Telegram) | openclaw pairing list --channel <channel> | openclaw pairing approve --channel <channel> <user-id> |
🥉 第三优先:日志定位
openclaw logs--tail30常见错误关键词与对策:
| 错误关键词 | 原因 | 对策 |
|---|---|---|
invalid api key/authentication_error | API Key 无效或未配置 | 1. Web UI 切换 Provider 2. 更新配置文件 apiKey |
pairing-pending | 设备 / 用户未批准 | devices approve或pairing approve |
contextWindow/compaction | 上下文超长 | /new;调大contextWindow和reserveTokensFloor |
blocked for inference | 账户受限 | 切换 Provider 或检查余额 |
第四优先:修改配置文件(最后手段)
操作前必做(备份):
cp~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak修改后必做:
openclaw config validate# 验证配置openclaw gateway restart# 重启生效第五优先:处理钉钉限流(2064)
这是AI 服务商限流,不是 OpenClaw / 钉钉的问题。对策:等待 1-5 分钟后重试;降低并发;联系服务商升级配额。
九、关键经验教训
- Web UI 优先于 CLI— 多数配置(尤其是模型选择)可 Web 端覆盖,更安全、更快捷。
- Provider 可以共存— 多个 Provider 不会冲突,关键是显式指定可用的那个。
- 日志是灯塔—
openclaw logs --tail 30比任何猜测都有效,所有关键错误都会在日志中显现。 - 配对命令要分清—
devices管 Web 连接,pairing --channel管消息频道。 - 上下文管理是长期健康的关键— 对于支持大上下文的模型,务必调大
contextWindow和reserveTokensFloor,避免频繁出现 compaction 错误。 (2064)不是钉钉的锅— 它是 AI 服务商限流的外显表现,不要误判为钉钉渠道故障。- 最复杂的问题,答案有时就在最简单的地方— Web UI 的下拉选择,胜过 CLI 和 JSON。
踩过的坑,比读过的书更有价值。
十、本次故障最终状态
| 检查项 | 状态 |
|---|---|
| Gateway 运行状态 | running |
| Connectivity probe | ok |
| Web 端消息回复 | ✅ 正常 |
| 钉钉消息回复 | ✅ 正常 |
命令行openclaw chat | ✅ 正常 |
| 长对话上下文 | 已调大阈值,稳定运行 |
钉钉(2064)限流 | 偶发,稍后重试可恢复 |
我是magicCzc,一个把 AIOps 当信仰的运维开发工程师。
GitHub:https://github.com/magicCzc