自动化排障

调度器和投递出了问题(cron + heartbeat),看这页。

排查流程

openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe

然后检查自动化状态:

openclaw cron status
openclaw cron list
openclaw system heartbeat last

Cron 没有触发

openclaw cron status
openclaw cron list
openclaw cron runs --id <jobId> --limit 20
openclaw logs --follow

正常情况下应该看到:

  • cron status 报告已启用,且有未来的 nextWakeAtMs
  • 任务已启用,调度规则和时区合法。
  • cron runs 显示 ok 或明确的跳过原因。

常见特征:

  • cron: scheduler disabled; jobs will not run automatically → cron 在配置或环境变量中被禁用了。
  • cron: timer tick failed → 调度器 tick 崩溃了;检查周围的堆栈/日志上下文。
  • 运行输出中 reason: not-due → 手动运行没加 --force,而任务还没到执行时间。

Cron 触发了但没有投递

openclaw cron runs --id <jobId> --limit 20
openclaw cron list
openclaw channels status --probe
openclaw logs --follow

正常情况下应该看到:

  • 运行状态为 ok
  • 隔离任务设置了投递模式/目标。
  • 频道探测报告目标频道已连接。

常见特征:

  • 运行成功但投递模式是 none → 本来就不会发外部消息。
  • 投递目标缺失或无效(channel/to) → 内部运行可能成功,但跳过了出站投递。
  • 频道认证错误(unauthorizedmissing_scopeForbidden) → 频道凭证/权限不够,投递被阻止。

Heartbeat 被抑制或跳过

openclaw system heartbeat last
openclaw logs --follow
openclaw config get agents.defaults.heartbeat
openclaw channels status --probe

正常情况下应该看到:

  • 心跳已启用且间隔不为零。
  • 上次心跳结果是 ran(或跳过原因你能理解)。

常见特征:

  • heartbeat skippedreason=quiet-hours → 不在 activeHours 范围内。
  • requests-in-flight → 主通道忙;心跳被推迟。
  • empty-heartbeat-file → 定期心跳被跳过,因为 HEARTBEAT.md 没有可执行内容且没有带标签的 cron 事件在队列中。
  • alerts-disabled → 可见性设置抑制了出站心跳消息。

时区和 activeHours 的坑

openclaw config get agents.defaults.heartbeat.activeHours
openclaw config get agents.defaults.heartbeat.activeHours.timezone
openclaw config get agents.defaults.userTimezone || echo "agents.defaults.userTimezone not set"
openclaw cron list
openclaw logs --follow

要点:

  • Config path not found: agents.defaults.userTimezone 说明这个键没设;心跳回退到主机时区(或 activeHours.timezone 如果设了的话)。
  • Cron 不加 --tz 就用 gateway 主机时区。
  • 心跳 activeHours 用配置的时区解析(userlocal 或显式 IANA 时区)。
  • ISO 时间戳不带时区时,cron at 调度按 UTC 处理。

常见特征:

  • 主机时区改了之后,任务在错误的墙上时间执行。
  • 白天心跳一直被跳过,因为 activeHours.timezone 设错了。

相关文档: