openclaw - 💡(How to fix) Fix [Bug] openclaw update 后旧 runtime-deps 残留导致 Gateway crash-loop 5小时 [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#73516Fetched 2026-04-29 06:18:57
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
closed ×1

Error Message

| 13:10:26 | 旧进程 reload 配置时发现 bundled feishu/whatsapp 要求 >=2026.4.25 → 版本检查失败 → shutdown error |

Fix Action

Fix / Workaround

临时 workaround(供其他用户参考)

openclaw gateway stop
find ~/.openclaw/plugin-runtime-deps/ -maxdepth 1 -type d \
  -name "openclaw-*" ! -name "openclaw-$(openclaw --version | grep -oE '\d+\.\d+\.\d+')-*" \
  ! -name "openclaw-unknown-*" -exec rm -rf {} \;
openclaw gateway start

Code Example

openclaw-2026.4.24-da6bdffc3d96/  ← 旧版本,4009JS 文件,完整核心代码
   openclaw-2026.4.26-da6bdffc3d96/  ← 新核心 deps,3621JS 文件
   openclaw-unknown-bd1f0b6280a9/    ← 新 channel layer deps,3509JS 文件

---

async function cleanupOldRuntimeDeps(currentVersion: string) {
  const depsDir = path.join(configDir, 'plugin-runtime-deps');
  const entries = await fs.readdir(depsDir);
  
  for (const entry of entries) {
    const match = entry.match(/^openclaw-(\d+\.\d+\.\d+)-/);
    if (match && match[1] !== currentVersion) {
      const fullPath = path.join(depsDir, entry);
      await fs.rm(fullPath, { recursive: true });
      log.info(`[update] cleaned up old runtime deps: ${entry}`);
    }
  }
}

---

openclaw gateway stop
find ~/.openclaw/plugin-runtime-deps/ -maxdepth 1 -type d \
  -name "openclaw-*" ! -name "openclaw-$(openclaw --version | grep -oE '\d+\.\d+\.\d+')-*" \
  ! -name "openclaw-unknown-*" -exec rm -rf {} \;
openclaw gateway start
RAW_BUFFERClick to expand / collapse

Bug: openclaw update 后旧 runtime-deps 目录残留导致 Gateway 启动崩溃

版本信息

  • 更新前版本: 2026.4.24
  • 更新后版本: 2026.4.26
  • OS: macOS 26.4.1 (arm64), Node 25.9.0
  • 安装方式: npm global (openclaw update)

现象

openclaw update 执行完成后,Gateway 崩溃退出。之后 5 小时内反复启动失败(launchd crash-loop throttle 搁置),直到手动清理旧 plugin-runtime-deps 目录后才恢复。

根因分析(详细数据)

时间线

时间 (GMT+8)事件
13:08openclaw update 执行,npm 安装 2026.4.26
13:10:25旧 Gateway 进程 (v2026.4.24) 收到 SIGTERM
13:10:26旧进程 reload 配置时发现 bundled feishu/whatsapp 要求 >=2026.4.25 → 版本检查失败 → shutdown error
13:10 ~ 18:12launchd 反复启动新 Gateway 二进制 → 进程在到达日志输出前崩溃 → launchd throttle 搁置 5 小时
18:12手动 stop → mv 旧 runtime-deps → start → 恢复

崩溃原因(两层叠加)

  1. 旧进程版本检查失败:更新完成后旧 Gateway 进程 (v2026.4.24) 还在运行,收到重启信号后加载配置,发现 2026.4.26 的 bundled feishu/whatsapp plugin 要求 >=2026.4.25,但自身是 2026.4.24 → 报错退出。

  2. 新进程因旧 runtime-deps 残留而崩溃(核心问题):launchd 用新二进制 (2026.4.26) 重启 Gateway,但 plugin-runtime-deps/ 中同时存在三个目录:

    openclaw-2026.4.24-da6bdffc3d96/  ← 旧版本,4009 个 JS 文件,完整核心代码
    openclaw-2026.4.26-da6bdffc3d96/  ← 新核心 deps,3621 个 JS 文件
    openclaw-unknown-bd1f0b6280a9/    ← 新 channel layer deps,3509 个 JS 文件
    • 目录按字典序排列:2026.4.24 < 2026.4.26,旧目录先被扫描
    • 旧目录没有 package.json(runtime-deps 只有 .openclaw-runtime-deps.json),但 dist/ 中包含完整的 OpenClaw 核心模块(min-host-versionversion 等底层模块)
    • 2026.4.26 引入了从单一 deps 到分层 deps 的架构变更,但 openclaw update 流程没有清理旧格式目录
    • 新 Gateway 二进制在启动阶段扫描到旧 dist/ 目录,模块加载冲突 → Node.js 初始化阶段 crash,连 logger 都来不及输出

证据

  • gateway.err.log 从 13:10:26 直接跳到 18:12:36,中间无任何新进程日志
  • macOS launchd 显示 runs = 2(进程在 10 秒内退出被视为 crash,不计入正常 runs)
  • 手动 mv 旧目录后立即启动成功
  • 旧 dist/ 和新 dist/ 有大量同名但内容不同的 JS 文件

建议解决方案

openclaw update 流程中增加自动清理步骤:

  1. npm install 完成后,扫描 plugin-runtime-deps/ 目录
  2. 识别目录命名格式 openclaw-{version}-{hash}openclaw-unknown-{hash}
  3. 调用 resolveBinaryVersion() 获取当前安装版本
  4. 删除版本号与当前版本不匹配的旧目录(openclaw-unknown-* 保留)
  5. 日志输出清理了哪些目录
  6. 最后执行冷重启(hard restart,不是旧进程 reload)

伪代码:

async function cleanupOldRuntimeDeps(currentVersion: string) {
  const depsDir = path.join(configDir, 'plugin-runtime-deps');
  const entries = await fs.readdir(depsDir);
  
  for (const entry of entries) {
    const match = entry.match(/^openclaw-(\d+\.\d+\.\d+)-/);
    if (match && match[1] !== currentVersion) {
      const fullPath = path.join(depsDir, entry);
      await fs.rm(fullPath, { recursive: true });
      log.info(`[update] cleaned up old runtime deps: ${entry}`);
    }
  }
}

临时 workaround(供其他用户参考)

openclaw gateway stop
find ~/.openclaw/plugin-runtime-deps/ -maxdepth 1 -type d \
  -name "openclaw-*" ! -name "openclaw-$(openclaw --version | grep -oE '\d+\.\d+\.\d+')-*" \
  ! -name "openclaw-unknown-*" -exec rm -rf {} \;
openclaw gateway start

extent analysis

TL;DR

The most likely fix is to implement an automatic cleanup step in the openclaw update process to remove old plugin-runtime-deps directories that do not match the current version.

Guidance

  • Identify and delete old plugin-runtime-deps directories that do not match the current version to prevent module loading conflicts.
  • Use the resolveBinaryVersion() function to get the current installed version and compare it with the version in the directory names.
  • Implement a cleanup function like cleanupOldRuntimeDeps to automate this process.
  • Consider adding logging to track which directories are cleaned up.

Example

The provided pseudo-code snippet in TypeScript demonstrates how to implement the cleanupOldRuntimeDeps function:

async function cleanupOldRuntimeDeps(currentVersion: string) {
  const depsDir = path.join(configDir, 'plugin-runtime-deps');
  const entries = await fs.readdir(depsDir);
  
  for (const entry of entries) {
    const match = entry.match(/^openclaw-(\d+\.\d+\.\d+)-/);
    if (match && match[1] !== currentVersion) {
      const fullPath = path.join(depsDir, entry);
      await fs.rm(fullPath, { recursive: true });
      log.info(`[update] cleaned up old runtime deps: ${entry}`);
    }
  }
}

Notes

This solution assumes that the openclaw update process has access to the necessary file system permissions and that the resolveBinaryVersion() function returns the correct current version.

Recommendation

Apply the workaround by implementing the cleanupOldRuntimeDeps function in the openclaw update process to automatically remove old plugin-runtime-deps directories and prevent module loading conflicts. This will ensure a smooth update process and prevent crashes due to outdated dependencies.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING