openclaw - 💡(How to fix) Fix Bug: peer dep removal is recurrent (not install-only) — npm tree resolution prunes channel deps on any npm op, causing watchdog cascade outage [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#63309Fetched 2026-04-09 07:55:26
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

The channel plugin peer dependency issue (tracked in #61787, #62272, #62994, #63043, #63231) is not only a fresh-install problem. The 5 missing packages can be silently removed while the gateway is running by any subsequent npm install operation executed in the openclaw package directory — including the postinstall-bundled-plugins.mjs hook that openclaw itself triggers. This creates a recurrent failure pattern that defeats manual reinstall workarounds.

More critically: when the missing deps are detected by the watchdog's openclaw config validate (Layer 3 health check), the watchdog misclassifies the state as gateway down rather than gateway degraded, triggering a forced restart. The restarted gateway then crashes immediately on module load, enters a crash loop, hits the watchdog's circuit breaker, and the gateway is fully offline — even though the running process was serving requests normally before the restart.

Root Cause

Root cause (confirmed)

Fix Action

Fix / Workaround

The channel plugin peer dependency issue (tracked in #61787, #62272, #62994, #63043, #63231) is not only a fresh-install problem. The 5 missing packages can be silently removed while the gateway is running by any subsequent npm install operation executed in the openclaw package directory — including the postinstall-bundled-plugins.mjs hook that openclaw itself triggers. This creates a recurrent failure pattern that defeats manual reinstall workarounds.

Option C (workaround-in-code): Make openclaw config validate return a structured degraded state (not invalid) when the specific failure is a missing peer dep MODULE_NOT_FOUND — so external health monitors can distinguish "peer dep missing, gateway serving" from "config structurally broken, gateway degraded."

Code Example

npm install --omit=dev --no-save --package-lock=false [missing bundled extension deps]

---

19:15:25  Gateway starts. All channels load. WS traffic normal.
          (peer deps present on disk; gateway runtime does NOT require them
           directly — bundled dist handles channel I/O. Config validate does.)
19:28:26  Watchdog Layer 3 runs: `openclaw config validate`
          → loads dist/ui-ztuR6rec.jsCannot find module '@buape/carbon'
L3 FAIL. Watchdog counts as health failure.
19:28:33  FAIL #1: watchdog forces restart. Gateway crashes on module load.
19:29:42  FAIL #2: crash loop continues.
19:31:05  FAIL #3: circuit breaker armed.
19:42:31  CIRCUIT BREAKER: watchdog stops restart attempts. Gateway offline.
19:51:24  Manual recovery: npm install 5 packages, gateway restart.

---

"peerDependencies": {
  "@buape/carbon": "*",
  "grammy": "*",
  "@grammyjs/runner": "*",
  "@larksuiteoapi/node-sdk": "*",
  "@slack/web-api": "*"
}
RAW_BUFFERClick to expand / collapse

Bug type

Regression / Recurrence (works after manual fix, breaks again on next npm operation)

Beta release blocker

No — but it's a reliability multiplier for self-hosted production deployments

Summary

The channel plugin peer dependency issue (tracked in #61787, #62272, #62994, #63043, #63231) is not only a fresh-install problem. The 5 missing packages can be silently removed while the gateway is running by any subsequent npm install operation executed in the openclaw package directory — including the postinstall-bundled-plugins.mjs hook that openclaw itself triggers. This creates a recurrent failure pattern that defeats manual reinstall workarounds.

More critically: when the missing deps are detected by the watchdog's openclaw config validate (Layer 3 health check), the watchdog misclassifies the state as gateway down rather than gateway degraded, triggering a forced restart. The restarted gateway then crashes immediately on module load, enters a crash loop, hits the watchdog's circuit breaker, and the gateway is fully offline — even though the running process was serving requests normally before the restart.

Root cause (confirmed)

npm v7+ tree resolution removes undeclared packages on every npm install.

The 5 channel plugin peer dependencies are absent from openclaw's package.json:

PackageChannelStatus in package.json
@buape/carbonDiscordnot declared
grammyTelegramnot declared
@grammyjs/runnerTelegram runnernot declared
@larksuiteoapi/node-sdkLark/Feishunot declared
@slack/web-apiSlacknot declared

These packages ARE required at runtime by dist/extensions/*/channel-plugin-api.js and by dist/ui-ztuR6rec.js (loaded by openclaw config validate). They are NOT in dependencies, peerDependencies, or optionalDependencies in package.json.

Recurrence vector: postinstall-bundled-plugins.mjs

scripts/postinstall-bundled-plugins.mjs runs after every npm install as the postinstall hook. It calls:

npm install --omit=dev --no-save --package-lock=false [missing bundled extension deps]

in the openclaw package root. In npm ≥ v7, every npm install — even targeted with --no-save --package-lock=false — performs full dependency tree resolution. Packages not present in the resolved tree are candidates for removal. Since the 5 peer deps are invisible to the tree (not declared), they are silently pruned.

Timeline of a recurrence incident (observed on 2026.4.8, production deployment):

19:15:25  Gateway starts. All channels load. WS traffic normal.
          (peer deps present on disk; gateway runtime does NOT require them
           directly — bundled dist handles channel I/O. Config validate does.)
19:28:26  Watchdog Layer 3 runs: `openclaw config validate`
          → loads dist/ui-ztuR6rec.js → Cannot find module '@buape/carbon'
          → L3 FAIL. Watchdog counts as health failure.
19:28:33  FAIL #1: watchdog forces restart. Gateway crashes on module load.
19:29:42  FAIL #2: crash loop continues.
19:31:05  FAIL #3: circuit breaker armed.
19:42:31  CIRCUIT BREAKER: watchdog stops restart attempts. Gateway offline.
19:51:24  Manual recovery: npm install 5 packages, gateway restart.

Duration of outage from a previously healthy gateway: ~23 minutes.

The running gateway was serving requests normally. The watchdog restart converted degraded (config validate broken)fully offline.

Steps to reproduce (recurrence)

  1. Install and recover from the initial peer dep issue (manually npm install @buape/carbon grammy @grammyjs/runner @larksuiteoapi/node-sdk @slack/web-api --prefix ...)
  2. Run any openclaw command that triggers an npm install in the package directory (upgrade, plugin install, any command that invokes the postinstall hook)
  3. Peer deps are silently removed
  4. Next watchdog L3 cycle triggers restart cascade → crash loop → outage

Expected behavior

  1. npm install -g openclaw installs and retains all runtime-required packages, including channel peer deps
  2. Subsequent npm install operations in the openclaw package directory do NOT remove packages required at runtime
  3. Watchdog correctly classifies "config validate fails due to missing peer dep" as degraded (not down) when the gateway HTTP health endpoint returns 200 OK

Proposed fix

Option A (correct, permanent fix): Declare the 5 packages in peerDependencies in package.json:

"peerDependencies": {
  "@buape/carbon": "*",
  "grammy": "*",
  "@grammyjs/runner": "*",
  "@larksuiteoapi/node-sdk": "*",
  "@slack/web-api": "*"
}

npm v7+ automatically installs peerDependencies on npm install -g. This also prevents tree resolution from pruning them on subsequent installs.

Option B (belt-and-suspenders): Add the 5 packages to the postinstall-bundled-plugins.mjs discovery scope so the postinstall hook reinstalls them if missing, identical to how it handles bundled extension runtime deps.

Option C (workaround-in-code): Make openclaw config validate return a structured degraded state (not invalid) when the specific failure is a missing peer dep MODULE_NOT_FOUND — so external health monitors can distinguish "peer dep missing, gateway serving" from "config structurally broken, gateway degraded."

Option A is the correct fix. Options B and C are defence-in-depth.

Watchdog note (for self-hosted deployments with external health monitoring)

If you run a watchdog that acts on openclaw config validate output:

  • A peer dep MODULE_NOT_FOUND failure should be classified as alert-only / degraded when the gateway HTTP /health endpoint returns {"ok":true}
  • Forcing a gateway restart on this condition converts a serving gateway into a crash loop
  • The gateway runtime does NOT require the 5 peer deps at startup — only the config validator (external process) does. The running process is unaffected.

OpenClaw version

2026.4.8 (confirmed). Also reproduced in 2026.4.5 per #61787, #62272, #62446, #62243.

Operating system

macOS 26.x (Apple Silicon, arm64)

Install method

npm global (npm install -g openclaw)

Related issues

  • #61787 — root cause tracking issue (npm global install omits channel deps)
  • #62272, #62568, #62994, #63043, #63225, #63231 — symptom reports for @buape/carbon
  • #60263 — grammy peer dep not auto-installed
  • #59286 — bundled plugin deps not installed after update
  • #62759 — openclaw doctor --fix fails (chicken-and-egg when config load requires missing deps)

extent analysis

TL;DR

Declare the 5 missing packages in peerDependencies in package.json to prevent npm v7+ from removing them on subsequent installs.

Guidance

  • Identify the 5 missing packages (@buape/carbon, grammy, @grammyjs/runner, @larksuiteoapi/node-sdk, @slack/web-api) and declare them in peerDependencies in package.json.
  • Verify that subsequent npm install operations do not remove these packages by checking the node_modules directory.
  • Consider implementing Option B or C as a defence-in-depth measure to prevent similar issues in the future.
  • Update the watchdog configuration to classify peer dep MODULE_NOT_FOUND failures as alert-only / degraded when the gateway HTTP /health endpoint returns {"ok":true}.

Example

"peerDependencies": {
  "@buape/carbon": "*",
  "grammy": "*",
  "(@grammyjs/runner": "*",
  "@larksuiteoapi/node-sdk": "*",
  "@slack/web-api": "*"
}

Notes

  • This fix assumes that the 5 missing packages are required at runtime by the dist/extensions/*/channel-plugin-api.js and dist/ui-ztuR6rec.js files.
  • The postinstall-bundled-plugins.mjs hook may still be triggered after installing the missing packages, but it should not remove them since they are now declared in peerDependencies.

Recommendation

Apply the proposed fix by declaring the 5 missing packages in peerDependencies in package.json, as this is the correct and permanent fix for the issue.

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…

FAQ

Expected behavior

  1. npm install -g openclaw installs and retains all runtime-required packages, including channel peer deps
  2. Subsequent npm install operations in the openclaw package directory do NOT remove packages required at runtime
  3. Watchdog correctly classifies "config validate fails due to missing peer dep" as degraded (not down) when the gateway HTTP health endpoint returns 200 OK

Still need to ship something?

×6

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

Back to top recommendations

TRENDING