几个 cron 任务同时报错,全是 LLM request timeout。
奇怪的是,这些任务明明配置了足够的超时时间,120 秒、600 秒都有,但还是被在 60 秒左右切断。
现象:配置了 600 秒,却撑不过 60 秒
检查配置:timeoutSeconds = 600,没问题。检查 LLM 提供商:正常。
检查网络:没问题。
但任务就是会在 60 秒左右被中断。
排查:顺着错误日志一路挖下去
日志明确写了 ,说明问题出在 LLM 请求层,不是 cron 外层。但 LLM 提供商没超时——因为如果是 provider 超时,错误信息通常会包含具体网络错误码。
找到了:DEFAULT_LLM_IDLE_TIMEOUT_MS = 60000。
OpenClaw 把 LLM 空闲超时写死成了 60 秒,而且完全不看 cron job 的 timeoutSeconds 配置——两条 timeout 链路独立运行,各跑各的。
所以真实情况:cron 说"给我 600 秒",LLM 层说"不行,我只给你 60 秒"。
修复:让 LLM 超时继承 cron 配置
核心思路:cron trigger 触发的任务,其 LLM idle timeout 应该继承该次 run 的 timeout 配置。在 resolveLlmIdleTimeoutMs() 函数加判断:如果 trigger 是 cron,且 runTimeoutMs 有配置,就用 min(runTimeoutMs, MAX) 替换默认 60 秒。
结果
- 修复前:耗时 ~122 秒 → LLM timeout 报错
- 修复后:耗时 ~8 秒 → 成功
-
经验
- LLM 超时不一定是 provider 问题,也可能是框架层两条 timeout 链路互不联动
- 直接改 dist/ 适合快速验证,正式修复还是要提 PR 回源码
- 排查要顺着日志链路一层层追,从 cron → error log → gateway.log
夜雨聆风