Administrator
发布于 2026-05-04 / 11 阅读
0

OpenClaw 更新后 QQ Bot 失联:不是打包漏了,是架构变了


5月3日下午,我照例更新了 OpenClaw 到 v2026.5.2,然后 QQ Bot 就没动静了。后来查 GitHub 才发现,这不是 bug——而是一次设计变更带来的迁移事故。


现象


更新完,QQ Bot 不回消息。openclaw status 的 Channels 表空白。配置完好,token 没丢。去 session 文件看,最后一次连接停在更新前。日志里连个错都没有——插件直接不加载了。


翻 dist 目录,正常的频道插件(比如 Telegram)长这样:



/app/dist/extensions/telegram/
  index.js ✅
  api.js ✅
  ... 20+ JS 文件

QQ Bot 长这样:



/app/dist/extensions/qqbot/
  openclaw.plugin.json   ← 只有元数据
  package.json           ← 只有包描述
  skills/                ← 空目录
  零个 JS 文件

第一反应当然是「打包漏了」。从 plugin-runtime-deps 翻出旧版(v2026.4.29)的编译 JS,22 个文件,全部复制到 dist 目录,重启容器,好了。确认兼容性没问题,旧版 JS 在新版 gateway 上跑得挺稳。


到这里我以为是 OpenClaw 的 CI 构建又掉了链子。这种事情历史上出过好几次——#71730、#70096、#61686,打包和依赖缺失算是老毛病。


等一下,不是漏掉的,是故意删掉的


查到 GitHub 才发现事情没那么简单。


#77483 解释了一切:v2026.5.x 系列把 25 个频道和非频道插件从「内置 bundled」(JS 随 Docker 镜像分发)改为「外置 external」(独立 npm 包,按需安装)。QQ Bot 是其中之一。受影响的全列表:

acpx, bluebubbles, brave, codex, diagnostics-otel, diagnostics-prometheus,
diffs, discord, feishu, google-meet, googlechat, line, lobster,
memory-lancedb, msteams, nextcloud-talk, nostr, qqbot, synology-chat, tlon,
twitch, voice-call, whatsapp, zalo, zalouser

外置化的意思:这些插件的独立 npm 包(如 @openclaw/qqbot)已发布到 npm registry,Docker 镜像就不再带它们的编译产物了。dist 目录里只留元数据——plugin.json 和 package.json,用于提供插件清单信息(比如 config schema、catalog 注册等),但不包含实际可运行的代码。


所以不是我一开始以为的「漏了」,是有意为之


但问题出在迁移上——从 v2026.4.x 升级到 v2026.5.x 时:


  • 没有自动安装对应的 external npm 包
  • 没有迁移提示(「你以前用的 QQ Bot 现在需要手动安装」)
  • `channels.qqbot` 配置还在但插件加载不到,日志里只静默跳过

  • 这三个缺陷加起来就是一次完美的静默失联。


    2026.5.2 刚重启为啥能用?


    因为插件加载走两条路:Loaded 注册表(外部安装的)优先,Bundled(镜像自带的)兜底。


    v2026.5.2 刚启动时,plugin-runtime-deps 里旧版 QQ Bot 被扫进 loaded 表,第一步就命中了。后来 openclaw.json 被写入触发了 config reload,loaded 表清空重建,旧版插件没再注册回来——fallback 到 bundled,发现是空壳,就没了。


    到 v2026.5.3 完全重启,loaded 表从零开始,从头就找不到。


    这个设计变更是怎么被补上的


    发现的时候(5/4),社区已经有人在跟进了。


    我是看了 #77424——另一位用户遇到了完全一样的问题,不过是 Feishu 插件。同一个 Docker 镜像,同一个症状,同一个根因。


    OpenClaw 团队的回应(5/4 夜间,GMT+8 今早)是三个 PR:


  • **[#77547](https://github.com/openclaw/openclaw/pull/77547)** — Docker 构建时显式 prune 外置插件的 dist 目录。这个 PR 把「dist 不留编译产物」的设计意图固化进了构建脚本,不再是半吊子状态(留元数据但不留代码)。
  • **[#77502](https://github.com/openclaw/openclaw/pull/77502)** — 当配置里引用了未安装的外置插件时,提示「这个插件需要安装,跑 `openclaw plugins install @openclaw/`」而不是说「stale config,删掉」。
  • **[#77604](https://github.com/openclaw/openclaw/pull/77604)** — 4→5 升级时自动恢复已配置的外部插件。这个是最理想的修复,**但被 close 了没合**。

  • 另外还有个附带修复——#77450 修了 plugin API 版本比较 bug:v2026.5.3-1 的 -1 后缀被通用 semver 比较当 prerelease 拒绝,导致所有 >=2026.5.3 的插件都装不了。这个跟 Docker 镜像 dist 缺失是两回事,但对通过 npm 安装插件的人影响很大。这是 #77293 被关闭的原因——但 #77293 的 issue 里另一个问题(install.runtime-*.js 缺失)其实没修。


    正确姿势 vs 现在的凑合


    未来的正确姿势:
    
    openclaw plugins install @openclaw/qqbot --dangerously-force-unsafe-install
    

    现在我用的 workaround(v2026.5.3-1 上)

    从旧版 plugin-runtime-deps 复制编译 JS 到 dist 目录。能用,但有一个隐患:#77547 引入的 prune 脚本会在未来的 Docker 镜像构建时主动清理外置插件 dist 目录。等到更新到包含 #77547 的版本时,这个 workaround 可能就不奏效了(如果 prune 在容器启动时也执行的话),或者至少文件结构会跟官方预期不一致。


    届时需要:清理手动复制的旧 JS 文件 → 用 openclaw plugins install @openclaw/qqbot 正式安装。


    还挂着的问题


  • QQ Bot 短回复(如 2 字符的「爱。」)不写 session 历史,Web 端看不到(#77309),v2026.5.2 出现,现在仍是 open
  • QQ Bot 消息重复发送,疑似 WebChat 轮询触发 message_sending hook(#77306),也是 open
  • 4→5 自动安装方案(#77604)被 close 且未合并,意味着下一个版本用户还是要手动装

  • 结论


    这个问题的完整面貌:


  • OpenClaw 在 v2026.5.x 将 25 个插件从内置改为外置 npm 包——**这是有意为之,方向合理**
  • 但迁移路径缺失——无自动安装、无提示、静默失败——**这是执行缺陷**
  • 官方 fix 已经合入 main(#77547 + #77502),但还没发布到 Docker 镜像
  • 最理想的一步到位方案 #77604 被搁置了

  • 对我个人来说,workaround 在 v2026.5.3-1 上能用,等后续版本出来要切到正式的 openclaw plugins install @openclaw/qqbot 方案。


    也给自己留个教训:遇到这种问题,第一直觉的「打包漏了」要打个问号。如果能早一点发现 #77483 里说的外置化意图,排查方向就会完全不同。