OpenClaw 2026.9.2 → 2026.9.4 升级事故复盘:两个 JSON 文件引发的连锁排障
四个独立故障根因 + 一套可直接套用的稳定升级 SOP

OpenClaw 2026.9.2 → 2026.9.4 升级事故复盘:两个 JSON 文件引发的连锁排障
一次看似普通的
openclaw update,实际花了整整一个晚上加一个早晨才完成。这篇文章完整记录了排障全过程、四个独立的故障根因,以及最后总结出的稳定升级流程。适合所有自托管 OpenClaw、遇到 update 失败或 Gateway 起不来的用户。
背景
环境:
- Ubuntu(systemd user service 部署)
- Node 通过 nvm 安装(v24.16.0),系统另有 /usr/bin/node
- OpenClaw 2026.9.2,npm 全局安装,Gateway 以 systemd user service 运行
- 5 个飞书通道、200+ 个 agent 目录
症状:openclaw update 升级到 2026.9.4 时,openclaw doctor 阶段失败:
✗ openclaw doctor
- Failed to migrate Skill Workshop proposal agnes-image-20260605-86fd8b3033:
Error: proposal draft hash does not match proposal metadata
- Failed to migrate Skill Workshop proposal agnes-video-20260605-e8839d11ff:
Error: proposal draft hash does not match proposal metadata
Doctor stopped because a state migration refused to continue.而且更糟的是,update 失败后 Gateway 直接起不来了。
事后看,这次事故其实是四个独立问题叠加:
- Skill Workshop 的遗留提案文件导致迁移拒绝
- 失败的 update 把主库 schema 迁移到一半
- 老旧的 systemd service unit 导致更新 handoff 失败
- 更新器 60 秒健康检查窗口对慢启动的 Gateway 太短(假警报)
下面按时间线逐一展开。

第一个问题:迁移拒绝 —— 元凶不在数据库里
排查思路
报错说的是 “Skill Workshop proposal”,第一反应是查主状态库 ~/.openclaw/state/openclaw.sqlite。用 Python 遍历所有表搜 agnes:
import sqlite3
db = sqlite3.connect('/home/oklife/.openclaw/state/openclaw.sqlite')
tables = [r[0] for r in db.execute(
"SELECT name FROM sqlite_master WHERE type='table'")]
for t in tables:
for row in db.execute(f'SELECT * FROM "{t}"'):
if 'agnes' in str(row):
print(t, row)结果:零命中。 数据库里根本没有 agnes。
那迁移器是从哪里读到这两个 proposal 的?换思路,直接全盘搜索文件系统(排除 node_modules,否则巨慢):
grep -rl "agnes-image-20260605" ~/.openclaw 2>/dev/null | grep -v node_modules
find ~/.openclaw -name "*.sqlite*" -not -path "*node_modules*" 2>/dev/null结果定位到了真凶:
~/.openclaw/skill-workshop/proposals/agnes-image-20260605-86fd8b3033/proposal.json
~/.openclaw/skill-workshop/proposals/agnes-video-20260605-e8839d11ff/proposal.jsonSkill Workshop 的提案是以 JSON 文件形式存在磁盘上的,迁移器读这些文件往数据库表里迁移。这两个 6 月份的提案(状态已是 rejected)文件里的 draftHash 和实际草稿文件对不上,迁移器直接拒绝继续,整个 update 卡死。
(grep 同时在一些 agent 的会话库和 media/inbound 里发现 agnes 字样,那些只是聊天记录文本,无害。)
关键教训
早前一次清理时,AI 助手只删除了数据库里的 proposal 记录行,没删磁盘上的提案目录,于是每次 update 都重新撞墙。对于"文件 + 数据库"双写的数据,清理时必须两头都清。
第二个问题:失败更新留下的半迁移 schema
删掉文件之前,先发现了更紧急的问题:update 失败后 Gateway 起不来了。
日志:
Gateway failed to start: SQLite schema is incomplete or noncanonical for
~/.openclaw/state/openclaw.sqlite
- column definitions differ for skill_workshop_collection_reviews
- missing or drifted index idx_skill_workshop_collection_reviews_workspace_time
- column definitions differ for skill_workshop_proposals
- column definitions differ for worker_environments三张表处于新旧 schema 之间的中间态。
一个容易踩的坑:integrity_check 会骗人
python3 -c "import sqlite3; print(sqlite3.connect(
'/home/oklife/.openclaw/state/openclaw.sqlite'
).execute('PRAGMA integrity_check;').fetchall())"
# 输出 [('ok',)]integrity_check 返回 ok,但 Gateway 还是起不来。原因是 integrity_check 只检查页结构物理完整性,不校验 schema 是否符合应用预期。半迁移的库物理上是好的,逻辑上是坏的。
修复:还原备份
好在升级前做过备份(~/openclaw-backup-<时间戳>/state)。恢复流程:
# 1. 停掉起不来的服务
systemctl --user stop openclaw-gateway.service
# 2. 把坏库挪开留档,还原 pre-update 备份
mv ~/.openclaw/state ~/.openclaw/state-broken-$(date +%F-%H%M%S)
cp -av ~/openclaw-backup-2026-09-17-223335/state ~/.openclaw/state
# 3. 确认提案目录内容后删除(根治)
ls -la ~/.openclaw/skill-workshop/proposals/agnes-image-20260605-86fd8b3033/
rm -rf ~/.openclaw/skill-workshop/proposals/agnes-image-20260605-86fd8b3033
rm -rf ~/.openclaw/skill-workshop/proposals/agnes-video-20260605-e8839d11ff
# 4. 验证库里没有残留
grep -c "agnes" ~/.openclaw/state/openclaw.sqlite || echo "clean"
# 5. 重启验证
openclaw gateway start
sleep 120
openclaw gateway status # Connectivity probe: ok ✓Gateway 回到 2026.9.2 正常运行,agnes 隐患根除。
第三个问题:update handoff 失败 —— 老旧 service unit 的锅
以为万事大吉,重跑 openclaw update,结果连续两次死在同一处。
现象:update 走到 activating 阶段后卡住,最终 Gateway 处于 failed 状态(exit 9 / SIGKILL),端口没人监听。
更新器的 handoff 日志 /tmp/openclaw-update-run-handoff-*/handoff.log 给出了答案:
handoff failed: Error: systemd service remained active or changed execution generation
recovery refused: parked systemd service identity changed or stop is incomplete配合 journalctl 看完整链条:
[gateway] received SIGTERM; shutting down
[gateway] draining active work before stop with timeout 315000ms: activeTasks=1
[gateway] still draining active work before stop: activeTasks=1 ← 每30秒刷一次
[gateway] active-work drain timeout reached; proceeding with shutdown
systemd: Main process exited, code=killed, status=9/KILL
systemd: Failed with result 'signal'失败链条:Gateway 收到停止指令 → 有一个活跃任务(实测主要是 Brave 浏览器的 websocket 连接)不肯结束 → drain 等 5 分钟超时 → systemd SIGKILL 强杀 → handoff 脚本看到服务以 signal 状态退出,判定"停得不干净" → 拒绝恢复 → 更新回滚,Gateway 无人拉起。

修复:重装 service unit
openclaw gateway status 一直有个提示:
Service config looks out of date or non-standard.
Service config issue: Gateway service PATH includes version managers...
Recommendation: reinstall with "openclaw gateway install --force"老 unit 是早期安装生成的(PATH 里带 nvm 路径等非标准内容),handoff 的 “changed execution generation” 校验就是被它绊倒的。重装:
openclaw gateway install --force输出确认:
Installed systemd service: ~/.config/systemd/user/openclaw-gateway.service
Previous unit backed up to: ...openclaw-gateway.service.bak顺带一提,如果这一步报 SERVICE_DEFINITION_UNKNOWN: [unsafe-permissions],检查并修掉 ~/.config 目录链上的 group/world 写权限:
stat -c '%A %U %G %n' ~/.config ~/.config/systemd ~/.config/systemd/user
chmod go-w ~/.config ~/.config/systemd ~/.config/systemd/user最终成功姿势:预先干净停服再更新
unit 修好后,采用"手动停服 → update"的姿势,绕开 handoff 的 drain/park 环节:
# 1. 先确认新 service 能正常跑
systemctl --user start openclaw-gateway.service
sleep 120
openclaw gateway status # Connectivity probe: ok ✓
openclaw channels status --probe # 飞书 5/5 connected ✓
# 2. 备份(必须做)
openclaw backup create
# 3. 关掉连着 Gateway 的浏览器标签页(减少活跃任务)
# 4. 干净停服——注意 stop 可能阻塞 5 分钟,不要 Ctrl+C
systemctl --user stop openclaw-gateway.service
systemctl --user reset-failed openclaw-gateway.service
ss -tlnp | grep 18789 || echo "port free"
# 5. 更新
openclaw update结果:
✓ global update (19.28s)
✓ openclaw doctor (123.21s) ← 迁移全部通过!
Phase: restarting
Phase: verifying
⚠️ OpenClaw update failed: restart-unhealthy. The gateway is running 2026.9.4.第四个问题(假警报):restart-unhealthy
最后这个 “failed” 把人吓一跳,但细看三行关键信息:
Gateway: restart failed: ... Gateway restart timed out after 60s waiting for health checks
Verification: gateway booted; service running; version verified.
⚠️ The gateway is running 2026.9.4.更新实际成功了。 只是 Gateway 预热要两分钟左右,超过更新器 60 秒的健康检查窗口,触发了一个假警报。验证确认:
openclaw --version # OpenClaw 2026.9.4 ✓
openclaw gateway status # Gateway version 2026.9.4, Connectivity probe: ok ✓
openclaw channels status --probe # 飞书 5/5 connected, works ✓
openclaw doctor --non-interactive # Doctor complete,无 error ✓遇到 restart-unhealthy 先别慌,跑一遍上面四条命令看实际状态,很可能已经升级完成。
收尾:插件版本对齐
Gateway 升到 2026.9.4 后,20 个官方插件仍 pin 在 2026.9.2。完整的逐个解 pin 命令、第三方插件处理原则和最终重启验收,见下文「收尾:插件版本对齐与最终重启」。

总结:OpenClaw 稳定升级 SOP
# ── 升级前 ──
openclaw backup create # 1. 备份,永远的第一步
openclaw gateway status # 2. 确认当前状态健康
openclaw doctor --non-interactive # 3. 体检,先解决 error 级问题
# 4. 关闭浏览器等长连接客户端
# ── 升级 ──
systemctl --user stop openclaw-gateway.service # 5. 预先干净停服
systemctl --user reset-failed openclaw-gateway.service
ss -tlnp | grep 18789 || echo "port free" # 6. 确认端口释放
openclaw update # 7. 更新
# ── 验收 ──
openclaw --version # 8. 版本确认
openclaw gateway status # 9. 连通性确认
openclaw channels status --probe # 10. 通道确认
openclaw doctor --non-interactive # 11. 终检五条核心教训
integrity_checkok ≠ 库没问题。它只验物理完整性;应用层的 “schema noncanonical” 要靠 Gateway 启动日志判断。- 迁移失败的数据源头可能不在数据库里。OpenClaw 的 Skill Workshop 提案是"磁盘 JSON 文件 + 数据库记录"双份的,排查时
grep -rl <关键词> ~/.openclaw | grep -v node_modules比只查库有效。 - service unit 过期会以最诡异的方式炸更新。handoff 报 “changed execution generation” 时,先
openclaw gateway install --force重装 unit。 - 预先手动停服是最稳的升级姿势。绕开 handoff 的 drain 等待,也就绕开了 “活跃任务 → drain 超时 → SIGKILL → handoff 拒绝恢复” 整条失败链。手动 stop 阻塞几分钟属正常,别 Ctrl+C。
restart-unhealthy可能是假警报。60 秒健康检查窗口对慢预热的实例太短,最终以openclaw --version+gateway status的实际状态为准。
附:关键路径速查
| 用途 | 路径 |
|---|---|
| 主状态库 | ~/.openclaw/state/openclaw.sqlite |
| Skill Workshop 提案 | ~/.openclaw/skill-workshop/proposals/<id>/proposal.json |
| 更新 handoff 日志 | /tmp/openclaw-update-run-handoff-*/handoff.log |
| Gateway 日志 | journalctl --user -u openclaw-gateway.service |
| 运行日志 | /tmp/openclaw/openclaw-YYYY-MM-DD.log |
| Triage 提示词 | ~/.openclaw/logs/support/openclaw-triage-prompt-*.md |
| 备份归档 | ~/YYYY-MM-DDT...-openclaw-backup.tar.gz |
收尾:插件版本对齐与最终重启
openclaw update 只把主程序升到 2026.9.4,不会自动解开官方插件的兼容 pin(doctor 会提示 20 active official plugins not on post-restart 2026.9.4)。完整步骤如下。
官方插件逐个解 pin
对官方插件要写目标版本,不能写成当前版本:
openclaw plugins update @openclaw/acpx@2026.9.4
openclaw plugins update @openclaw/cerebras-provider@2026.9.4
openclaw plugins update @openclaw/cloudflare-ai-gateway-provider@2026.9.4
openclaw plugins update @openclaw/comfy-provider@2026.9.4
openclaw plugins update @openclaw/exa-plugin@2026.9.4
openclaw plugins update @openclaw/feishu@2026.9.4
openclaw plugins update @openclaw/firecrawl-plugin@2026.9.4
openclaw plugins update @openclaw/gradium-speech@2026.9.4
openclaw plugins update @openclaw/inworld-speech@2026.9.4
openclaw plugins update @openclaw/llama-cpp-provider@2026.9.4
openclaw plugins update @openclaw/longcat-provider@2026.9.4
openclaw plugins update @openclaw/openshell-sandbox@2026.9.4
openclaw plugins update @openclaw/qwen-provider@2026.9.4
openclaw plugins update @openclaw/stepfun-provider@2026.9.4
openclaw plugins update @openclaw/synthetic-provider@2026.9.4
openclaw plugins update @openclaw/tavily-plugin@2026.9.4
openclaw plugins update @openclaw/tokenjuice@2026.9.4
openclaw plugins update @openclaw/vercel-ai-gateway-provider@2026.9.4
openclaw plugins update @openclaw/voyage-provider@2026.9.4
openclaw plugins update @openclaw/zai-provider@2026.9.4第三方插件单独判断
brave:如果被 pin 在旧版本,需要单独升到@2026.9.4。openclaw-weixin:属于第三方插件,不与官方2026.9.4对齐捆绑;如无明确需要,可保持现状。
原则:不顺手大面积升第三方插件,避免引入额外变量。
最终干净重启
插件更新完不代表运行时已加载,必须重启 Gateway:
systemctl --user stop openclaw-gateway.service
systemctl --user reset-failed openclaw-gateway.service
ss -tlnp | grep 18789 || echo "port free"
systemctl --user start openclaw-gateway.service
sleep 90
openclaw gateway status
openclaw channels status --probe如果 systemctl --user stop 再次卡住,先查:
journalctl --user -u openclaw-gateway.service -n 40 --no-pager看是否还是 drain / activeTasks / SIGKILL 这条链路。
最终验收标准
openclaw --version显示2026.9.4openclaw gateway status中 Gateway version 为2026.9.4Connectivity probe: ok- 飞书
5/5 connected, works openclaw doctor --lint --json不再提示官方插件版本漂移
回滚点
- 升级前 fresh backup
- 上一稳定版:
2026.9.2 - 本次变更边界:主程序
2026.9.4+ 官方插件对齐2026.9.4+ 个别第三方插件按需更新
环境:OpenClaw 2026.9.2 → 2026.9.4,Ubuntu + systemd user service,npm 安装。写于 2026-09-18。
关联阅读
- [[openclaw-2026-9-2-upgrade-troubleshooting]]
- [[openclaw-gateway-v8-gc-restart-loop]]
梦行志