OpenClaw 腾讯云一键更新后全面排障与恢复

0 阅读2分钟

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"
}

变更点:

  • botNamename
  • dmPolicyallowFromchannels.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(如 jjxstudybot)与 agents.list 中对应 agent 的 id 同名,v4.2 会自动按名称匹配路由
  • v3.x 使用 agent 的 bindings 字段做路由v4.2 已移除 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 的访问控制策略更严格。dmPolicyallowFrom 需要同时在飞书配置的顶层每个 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.12gateway 无法启动
飞书 botNamechannels.feishu.botNamechannels.feishu.name配置校验失败
dmPolicy 位置channels.feishu.dmPolicy顶层 dmPolicy配置校验失败
allowFrom 位置channels.feishu.allowFrom顶层 allowFrom配置校验失败
飞书必填字段domain: "feishu"配置校验失败

v3.28 → v4.2 破坏性变更清单

变更项v3.28v4.2影响
Agent 路由agents.list[].bindings按 account ID 自动匹配同名 agentbindings 字段导致配置校验失败
插件 APIv3 APIv4 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

建议

  1. 不要使用腾讯云一键更新——它只升级部分组件,不处理 Node.js 和配置迁移,极易导致半升级状态。
  2. 升级前备份配置cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak-$(date +%Y%m%d)
  3. 手动升级流程:先升级 Node.js → 再 pnpm add -g openclaw@<version> → 再 openclaw doctor --fix → 最后重启 gateway。
  4. 多账号场景:如果有多只飞书虾,升级后务必检查 accounts 中的每个凭证是否仍然有效,飞书开发者后台偶尔会因长期未使用而禁用应用。

来源文章