排障实录 02:改个模型名,把两个定时任务搞死了
2026-10-20 | 真实故障复盘 | 一个改名引发的连锁反应
一句话结论
改配置的时候,你改的是"定义";但系统里还有一堆地方存的是"引用"。定义改了,引用全断。
我改了一个模型名,一周内两个自动化任务静默失败,直到我截图排查才发现。
一、事故现场
一张控制台截图,顶部一条红色警告:
部分模型无法刷新。请打开"模型"重试。
任务列表里两条红色:
| 任务 | 计划 | 上次运行 | 状态 |
|---|---|---|---|
| RSI素材日收集 | 每天 23:00 | 15 小时前 | ❌ |
| behavior_loop周检 | 每周一 09:00 | 27 小时前 | ❌ |
它们已经连续失败了,但没有任何人收到通知——因为这两个任务都设了 delivery: none(静默模式)。
二、捞错误日志
# 列出所有自动化任务及其状态
openclaw automations list
关键字段出来了:
{
"name": "RSI素材日收集",
"lastRunStatus": "error",
"lastRunError": "automation model override 'deepseek-direct/deepseek-v4-flash' \
rejected by agents.defaults.modelPolicy.allow: \
deepseek-direct/deepseek-v4-flash is not in [api88/..., blockrun/..., \
deepseek-direct/deepseek-flash, deepseek-direct/deepseek-v4-pro, ...]"
}
翻译成人话:
- 任务里写死了模型
deepseek-direct/deepseek-v4-flash - 但允许清单里只有
deepseek-direct/deepseek-flash - 名字差一截,直接被拒绝执行
三、根因:三天前的一次改名
三天前我把模型名对齐到官方新命名:
- "deepseek-v4-flash" (旧名)
+ "deepseek-flash" (新名,指向同一个后端)
改的时候我只做了两件事:
- 改了 provider 的模型表
- 改了全局默认模型
漏了第三件事:检查有哪些任务/会话在硬编码引用旧名。
结果:
- 2 个自动化任务 → 失败
- 若干旧会话 → 界面上还显示旧名(但不影响运行,因为旧名 API 仍可调用)
四、修复
不需要重建任务,只需要改任务里的模型覆盖字段:
# 方式一:通过工具更新
automations update <jobId> '{"payload":{"model":"deepseek-direct/deepseek-flash"}}'
修复后:
| 任务 | 旧模型 | 新模型 | 下次运行 |
|---|---|---|---|
| RSI素材日收集 | deepseek-v4-flash ❌ | deepseek-flash ✅ | 今晚 23:00 |
| behavior_loop周检 | deepseek-v4-flash ❌ | deepseek-flash ✅ | 下周一 09:00 |
注意:lastRunStatus 不会自动刷新,要等下次实际运行成功才会变绿。这期间界面上还是红叉,属于正常现象。
五、顺手发现的第二个坑
改任务的时候注意到,behavior_loop周检 的 message 字段是:
峰哥行为层RSI闭环:每周自动扫描 corrections.md → 归集 → 标晋升...
结尾是个省略号——指令被截断了。
任务即使能跑,也会因为指令不完整而跑偏。
这说明:任务的 prompt 本身也会被截断,长指令要检查完整性。
六、第三个坑:白名单失真
排查时顺便看了模型白名单:
# 白名单原本 59 条
其中:
api88/*和blockrun/*占 55 条- 但 api88 的 token 报
401 Invalid token,blockrun 早就在冷却期
一个白名单里 93% 是死条目,等于形同虚设。
更严重的:安全审计报过一条 CRITICAL——
Small models (<=300B params) detected: api88/qwen3.5-35b-a3b
@ agents.defaults.model.fallbacks (unsafe; sandbox=off; web=[web_search, web_fetch, browser])
一个 35B 小模型,带联网工具,没有沙箱——它如果被 fallback 选中,就是个风险。
修复:白名单从 59 条砍到 4 条,全是实际在用的:
deepseek-direct/deepseek-flash text+image
deepseek-direct/deepseek-v4-pro text
deepseek-direct/deepseek-chat text
deepseek-direct/deepseek-reasoner text
七、四条可以抄走的经验
- 改任何一个"名字",都要全局搜一遍引用。 模型名、插件名、agent 名都一样。
- 静默任务失败了不会有人告诉你。 关键任务至少配一个失败告警通道。
- 任务 prompt 也会被截断。 长指令要检查结尾完整性。
- 白名单不是越多越安全。 一堆失效条目反而掩盖真正的风险。
八、一个更普适的教训
这次故障不是"改错了",而是"改完之后没有验证引用完整性"。
配置系统里,定义(definition)和引用(reference)是分开存储的。改定义的时候,引用不会自动跟着变,也不会报错——它只会在被使用的那一刻失败。
而如果那个"使用"发生在半夜、发生在静默任务里、发生在没有告警的地方,你就永远不知道它坏了。
所有日志和命令都是真实的,可复现。