先说结论
OpenClaw 的 cron 任务有两层结果:任务本身跑没跑成、推送有没有送达到。这两层是独立的。默认你只看得到第一层(任务 ok),第二层(推送 delivered)要专门查。
不查第二层 = 盲跑。 任务天天"成功",你却一条都没收到,还以为一切正常。
场景:今早发生了什么
2026-09-07,4 个走微信的 cron:
| 任务 | 设定时间 | 结果 |
|---|---|---|
| 内容工厂 | 01:30 | 任务 ok,微信没收到 |
| 养虾日报 | 06:30 | 任务 ok,微信没收到 |
| 每日项目日报 | 08:00 | 任务 ok,微信没收到 |
| 灵感雷达 | 09:04 | 任务 ok,微信没收到 |
全部 status: ok,全部 delivered: false。
自检清单(按这个顺序查)
第 1 步:看任务跑没跑成
openclaw cron runs --id <任务id> --limit 1
重点看 status 字段:
ok→ 任务本身跑成了,问题在推送层(往下查)- 非
ok→ 任务本身挂了,先修任务逻辑
第 2 步:看推送送到没
同一份 cron runs 输出里,看 delivery 段:
{
"intended": {"channel": "openclaw-weixin", "to": "o9cq80-...@im.wechat"},
"resolved": {"ok": true},
"fallbackUsed": true,
"delivered": false
}
三个字段一起看:
| 字段 | 含义 | 今天的值 |
|---|---|---|
resolved.ok |
投递目标解析成功 | true(知道往哪发) |
fallbackUsed |
用了备用路径 | true(主路径也试了,没成) |
delivered |
最终送达 | false(没到) |
resolved.ok: true + delivered: false = 目标找对了,但发送失败。典型是连接层断了。
第 3 步:查频道连接状态
openclaw status
看对应频道那行。本机显示 openclaw-weixin | ON | OK | configured——但 configured 只表示账号配好了,不代表长连接活着。
第 4 步:查心跳
openclaw status 里还有一行容易被忽略:
Last heartbeat failed · openclaw-weixin
心跳是维持长连接的保活机制。心跳失败 = 连接已断。 这是今天最关键的线索:最后一次成功推送是 09-06 06:34,09-07 全天 0 送达,说明连接在某个时间点断了,没自动恢复。
第 5 步:查失败事件列表
openclaw channels dead-letters list
这个命令列出失败的事件,能帮你确认是不是批量失败、失败时间点。
根因判断(诚实说明)
到写这篇时,根因还没 100% 定位。 两个候选:
- 凌晨网络抖动 → 长连接断开 → 没重连(最常见)
- 账号 session 过期 → 需要重新
openclaw channels login
已做的处置:
- 不动配置,先观察今晚新一轮 cron 是否自动恢复(长连接有时能自愈)
- 保留
dead-letters list作为后续排查入口
这篇的价值不在于"我修好了",而在于"下次你遇到同样情况,5 分钟就能定位到是推送层而不是任务层"。
怎么避免再踩(3 条)
- 别只看
status: ok。任务成功 ≠ 推送成功。定期查delivery.delivered。 - 心跳失败是预警。看到
Last heartbeat failed就该警惕,不等用户来问"今天怎么没收到"。 - cron 推送失败要告警,不能静默。任务成功但
delivered: false时,应该单独发一条告警给自己(比如发到 Telegram,因为 Telegram 是轮询比长连接稳),而不是默默当完成。
成本账单
| 项目 | 金额 |
|---|---|
| 排查用的命令 | ¥0(OpenClaw 内置) |
| 故障本身 | 0 元,只是没收到推送 |
下一步
微信长连接不稳是已知弱点。后续会写一篇《OpenClaw + Telegram/邮件兜底:推送失败自动切换渠道》,把"主渠道挂了自动走备用"做成标配。这样即使微信某天抽风,你也不会漏掉日报。
本文故障数据来自本机真实环境(2026-09-07 晨,openclaw-weixin 频道,账号 e471ee286ee5-im-bot),非推测。根因排查进行中。
