OpenClaw 腾讯云一键更新后全面排障与恢复
背景
腾讯云轻量应用服务器提供了 OpenClaw 的"一键更新"功能。点击后版本从 v3.11 直接跳到 v3.28,但更新完成后所有机器人(QQ、飞书、微信)全部失联,gateway 无法正常启动。
本文记录从发现问题到完全恢复 10 只飞书虾 + QQ Bot 的完整排障过程,所有操作均在服务器终端完成。
第一阶段:Gateway 完全无法启动
1.1 现象
systemctl --user status openclaw-gateway
# Active: activating (auto-restart) (Result: exit-code)
gateway 反复崩溃重启,日志中出现大量报错。
1.2 排查:Node.js 版本不满足要求
node -v
# v20.19.0
# 查看 gateway 日志
journalctl --user -u openclaw-gateway -n 50 --no-pager
# 发现:OpenClaw v3.28+ 要求 Node.js >= 22.12
根因:腾讯云一键更新只升级了 OpenClaw 本体,没有同步升级 Node.js。v3.28 依赖的 ESM 特性和原生 fetch 需要 Node.js 22+。
1.3 解决:升级 Node.js 到 v22 LTS
# 下载 Node.js v22 LTS
cd /tmp
wget https://nodejs.org/dist/v22.16.0/node-v22.16.0-linux-x64.tar.xz
# 解压到系统目录
tar -xf node-v22.16.0-linux-x64.tar.xz
rm -rf /usr/local/lib/nodejs/node-v22
mv node-v22.16.0-linux-x64 /usr/local/lib/nodejs/node-v22
# 更新环境变量(写入 ~/.bashrc)
export PATH="/usr/local/lib/nodejs/node-v22/bin:$PATH"
# 验证
node -v # v22.16.0
npm -v # 10.9.2
第二阶段:Gateway 启动后飞书配置校验失败
2.1 现象
Node.js 升级后 gateway 能启动,但立即报配置校验错误退出:
Invalid config at ~/.openclaw/openclaw.json:
- channels.feishu: Unrecognized key: "botName"
- channels.feishu: Unrecognized key: "dmPolicy"
- channels.feishu: Unrecognized key: "allowFrom"
2.2 根因:v3.28 配置 Schema 破坏性变更
v3.11 的飞书配置结构:
{
"channels": {
"feishu": {
"enabled": true,
"appId": "cli_xxx",
"appSecret": "xxx",
"botName": "小惠",
"dmPolicy": "open",
"allowFrom": "all"
}
}
}
v3.28+ 的新结构:
{
"channels": {
"feishu": {
"enabled": true,
"appId": "cli_xxx",
"appSecret": "xxx",
"name": "小惠",
"domain": "feishu"
}
},
"dmPolicy": "open",
"allowFrom": "all"
}
变更点:
botName→namedmPolicy和allowFrom从channels.feishu移到了配置顶层- 新增必填字段
domain: "feishu"
2.3 解决:迁移配置格式
# 备份
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak
# 用 Python 迁移配置
python3 -c "
import json
with open('/root/.openclaw/openclaw.json') as f:
data = json.load(f)
feishu = data['channels']['feishu']
# botName -> name
if 'botName' in feishu:
feishu['name'] = feishu.pop('botName')
# dmPolicy/allowFrom 移到顶层
for key in ['dmPolicy', 'allowFrom']:
if key in feishu:
data[key] = feishu.pop(key)
# 添加 domain
feishu.setdefault('domain', 'feishu')
with open('/root/.openclaw/openclaw.json', 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print('Config migrated')
"
第三阶段:插件版本不匹配导致 TypeError
3.1 现象
Gateway 启动后日志中出现约 36 个插件加载失败:
TypeError: Cannot read properties of undefined (reading 'xxx')
# 涉及所有模型 provider 插件
3.2 根因:OpenClaw 主体 = 3.28,插件 = 4.2
腾讯云一键更新把插件目录 ~/.openclaw/extensions/ 下的包升级到了 4.2 版本,但主程序只到 3.28。插件 API 与主程序版本不兼容。
3.3 决策:升级到 v4.2
先确认所有渠道插件(feishu、qqbot、wecom 等)是否兼容 4.2,确认无问题后执行升级:
# 全局安装 OpenClaw 4.2
export PNPM_HOME="/root/.local/share/pnpm"
export PATH="$PNPM_HOME:$PATH"
pnpm add -g openclaw@2026.4.2
# 运行 doctor 修复
openclaw doctor --fix
# 更新 systemd 服务文件(doctor 会自动处理)
systemctl --user daemon-reload
# 重启
systemctl --user restart openclaw-gateway
验证:
systemctl --user status openclaw-gateway
# Active: active (running)
# 确认版本
journalctl --user -u openclaw-gateway -n 5 --no-pager | grep "v20"
# OpenClaw Gateway (v2026.4.2)
第四阶段:QQ Bot 恢复,飞书仍然无响应
4.1 现象
Gateway 启动成功,QQ Bot 正常工作,但飞书机器人发消息没有任何反应。
4.2 排查:tenant_access_token 获取失败
# 查看飞书相关日志
grep "feishu" /tmp/openclaw/openclaw-2026-04-04.log | grep -i "error\|fail\|400" | tail -20
# AxiosError: Request failed with status code 400
# url: https://open.feishu.cn/open-apis/bot/v3/info
# Bot identities resolving as "unknown"
根因:飞书 tenant_access_token 获取失败 → 没有 Authorization header → bot/v3/info 返回 400。根源是配置中的 appId/appSecret 凭证失效。
4.3 排查:逐个验证凭证
# 验证单个飞书应用凭证是否有效
python3 -c "
import urllib.request, json
data = json.dumps({
'app_id': 'cli_xxx',
'app_secret': 'xxx'
}).encode()
req = urllib.request.Request(
'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
data=data,
headers={'Content-Type': 'application/json'}
)
resp = urllib.request.urlopen(req)
r = json.loads(resp.read())
print('code={} msg={}'.format(r.get('code'), r.get('msg')))
"
# code=0 msg=ok 表示有效
# code!=0 表示凭证无效
4.4 解决:清理无效凭证,保留有效账号
发现部分飞书应用凭证已失效(app unauthorized),通过修改 openclaw.json 移除无效账号,只保留凭证有效的账号。
第五阶段:恢复全部 10 只飞书虾的多账号配置
5.1 背景
系统中配置了 12 个 agent(小惠虾、金融虾、学习虾、客服虾、科技虾、战略虾、旅行虾、阅读虾、娱乐虾、热点虾、龙虾、博学虾),每只虾对应独立的飞书应用。一键更新后所有账号配置丢失,需要从历史会话记录中恢复。
5.2 从会话历史恢复凭证
# 会话文件位于
ls ~/.openclaw/agents/main/sessions/*.jsonl*
# 搜索所有飞书 appId
grep -roh 'cli_a9[0-9a-f]\{16\}' ~/.openclaw/agents/main/sessions/ | sort -u
# 搜索 setup_shrimp.py 调用记录(包含完整凭证)
grep -r "setup_shrimp.py" ~/.openclaw/agents/main/sessions/ | grep -o '"[^"]*setup_shrimp.py[^"]*"'
5.3 批量验证凭证
将所有找到的 appId + appSecret 组合写入验证脚本,逐个调用飞书 API 确认有效性:
# /tmp/verify_all.py
import urllib.request, json
creds = [
("小惠虾", "cli_xxx", "secret_xxx"),
("金融虾", "cli_xxx", "secret_xxx"),
# ... 其余虾
]
for name, app_id, app_secret in creds:
data = json.dumps({"app_id": app_id, "app_secret": app_secret}).encode()
req = urllib.request.Request(
"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
data=data,
headers={"Content-Type": "application/json"},
)
try:
resp = urllib.request.urlopen(req)
r = json.loads(resp.read())
status = "VALID" if r.get("code") == 0 else "INVALID"
except Exception as e:
status = "ERROR"
print("{}: {} ({})".format(name, status, app_id))
5.4 配置多账号
v4.2 的多飞书账号配置结构使用 accounts 字段:
{
"channels": {
"feishu": {
"enabled": true,
"domain": "feishu",
"dmPolicy": "open",
"allowFrom": "all",
"accounts": {
"default": {
"appId": "cli_小惠虾appId",
"appSecret": "小惠虾secret",
"name": "小惠虾",
"dmPolicy": "open",
"allowFrom": "all"
},
"jjx": {
"appId": "cli_金融虾appId",
"appSecret": "金融虾secret",
"name": "金融虾",
"dmPolicy": "open",
"allowFrom": "all"
}
}
}
}
}
关键点:
- 每个 account 的 key(如
jjx、studybot)与agents.list中对应 agent 的id同名,v4.2 会自动按名称匹配路由 v3.x 使用 agent 的,v4.2 已移除bindings字段做路由bindings,改为按 account ID 自动匹配同名 agent- 顶层的
appId/appSecret在使用accounts时应移除,避免混淆
5.5 配置写入示例
python3 -c "
import json
with open('/root/.openclaw/openclaw.json') as f:
data = json.load(f)
feishu = data['channels']['feishu']
feishu.pop('appId', None)
feishu.pop('appSecret', None)
feishu['dmPolicy'] = 'open'
feishu['allowFrom'] = 'all'
feishu['accounts'] = {
'default': {
'appId': 'cli_xxx', 'appSecret': 'xxx',
'name': '小惠虾', 'dmPolicy': 'open', 'allowFrom': 'all'
},
'jjx': {
'appId': 'cli_xxx', 'appSecret': 'xxx',
'name': '金融虾', 'dmPolicy': 'open', 'allowFrom': 'all'
},
# ... 其余账号
}
with open('/root/.openclaw/openclaw.json', 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print('Done')
"
第六阶段:飞书报 "access not configured"
6.1 现象
所有飞书虾的 WebSocket 已连接、bot open_id 已解析,但用户给小惠虾发消息时收到:
OpenClaw: access not configured.
Your Feishu user id: ou_xxx
Pairing code: DBDM4JU8
6.2 根因
v4.2 的访问控制策略更严格。dmPolicy 和 allowFrom 需要同时在飞书配置的顶层和每个 account 中设置:
{
"channels": {
"feishu": {
"enabled": true,
"domain": "feishu",
"dmPolicy": "open",
"allowFrom": "all",
"accounts": {
"default": {
"appId": "cli_xxx",
"appSecret": "xxx",
"name": "小惠虾",
"dmPolicy": "open",
"allowFrom": "all"
}
}
}
}
}
6.3 解决
python3 -c "
import json
with open('/root/.openclaw/openclaw.json') as f:
data = json.load(f)
feishu = data['channels']['feishu']
feishu['dmPolicy'] = 'open'
feishu['allowFrom'] = 'all'
for acc in feishu.get('accounts', {}).values():
acc['dmPolicy'] = 'open'
acc['allowFrom'] = 'all'
with open('/root/.openclaw/openclaw.json', 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print('Done')
"
systemctl --user restart openclaw-gateway
踩坑总结
v3.11 → v3.28+ 破坏性变更清单
| 变更项 | 旧版 (v3.11) | 新版 (v3.28+) | 影响 |
|---|---|---|---|
| Node.js 要求 | >= 18 | >= 22.12 | gateway 无法启动 |
| 飞书 botName | channels.feishu.botName | channels.feishu.name | 配置校验失败 |
| dmPolicy 位置 | channels.feishu.dmPolicy | 顶层 dmPolicy | 配置校验失败 |
| allowFrom 位置 | channels.feishu.allowFrom | 顶层 allowFrom | 配置校验失败 |
| 飞书必填字段 | 无 | domain: "feishu" | 配置校验失败 |
v3.28 → v4.2 破坏性变更清单
| 变更项 | v3.28 | v4.2 | 影响 |
|---|---|---|---|
| Agent 路由 | agents.list[].bindings | 按 account ID 自动匹配同名 agent | bindings 字段导致配置校验失败 |
| 插件 API | v3 API | v4 API | 插件版本必须与主体一致 |
| 访问控制 | 顶层 dmPolicy 即可 | 顶层 + 每个 account 都需要 | 用户收到 "access not configured" |
关键排障命令速查
# 查看 gateway 状态
systemctl --user status openclaw-gateway
# 查看最近日志
journalctl --user -u openclaw-gateway -n 50 --no-pager
# 查看当天详细日志
cat /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log | python3 -m json.tool | less
# 过滤飞书连接日志
grep "bot open_id" /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log
# 过滤错误
grep -i "error\|fail\|invalid" /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log | tail -20
# 验证飞书凭证
python3 -c "
import urllib.request, json
data = json.dumps({'app_id': 'YOUR_APP_ID', 'app_secret': 'YOUR_SECRET'}).encode()
req = urllib.request.Request('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', data=data, headers={'Content-Type': 'application/json'})
r = json.loads(urllib.request.urlopen(req).read())
print(r)
"
# 重启 gateway
systemctl --user restart openclaw-gateway
# 运行 doctor
openclaw doctor --fix
# 配置文件位置
cat ~/.openclaw/openclaw.json | python3 -m json.tool
建议
- 不要使用腾讯云一键更新——它只升级部分组件,不处理 Node.js 和配置迁移,极易导致半升级状态。
- 升级前备份配置:
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak-$(date +%Y%m%d) - 手动升级流程:先升级 Node.js → 再
pnpm add -g openclaw@<version>→ 再openclaw doctor --fix→ 最后重启 gateway。 - 多账号场景:如果有多只飞书虾,升级后务必检查
accounts中的每个凭证是否仍然有效,飞书开发者后台偶尔会因长期未使用而禁用应用。