先说结论

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% 定位。 两个候选:

  1. 凌晨网络抖动 → 长连接断开 → 没重连(最常见)
  2. 账号 session 过期 → 需要重新 openclaw channels login

已做的处置:

  • 不动配置,先观察今晚新一轮 cron 是否自动恢复(长连接有时能自愈)
  • 保留 dead-letters list 作为后续排查入口

这篇的价值不在于"我修好了",而在于"下次你遇到同样情况,5 分钟就能定位到是推送层而不是任务层"。


怎么避免再踩(3 条)

  1. 别只看 status: ok。任务成功 ≠ 推送成功。定期查 delivery.delivered
  2. 心跳失败是预警。看到 Last heartbeat failed 就该警惕,不等用户来问"今天怎么没收到"。
  3. cron 推送失败要告警,不能静默。任务成功但 delivered: false 时,应该单独发一条告警给自己(比如发到 Telegram,因为 Telegram 是轮询比长连接稳),而不是默默当完成。

成本账单

项目 金额
排查用的命令 ¥0(OpenClaw 内置)
故障本身 0 元,只是没收到推送

下一步

微信长连接不稳是已知弱点。后续会写一篇《OpenClaw + Telegram/邮件兜底:推送失败自动切换渠道》,把"主渠道挂了自动走备用"做成标配。这样即使微信某天抽风,你也不会漏掉日报。


本文故障数据来自本机真实环境(2026-09-07 晨,openclaw-weixin 频道,账号 e471ee286ee5-im-bot),非推测。根因排查进行中。