You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Regression (worked before, now fails) — same packaging-regression family as #77896 (Matrix) and the cluster of closed issues #71484, #74692, #74899, #75032, #75056, #75206.
Summary
After updating to OpenClaw 2026.5.4 on a Homebrew-managed install, every main-session lane crashes immediately with ERR_MODULE_NOT_FOUND because @openclaw/codex@2026.5.3 cannot resolve openclaw/plugin-sdk/* at runtime. The plugin declares peerDependencies: { "openclaw": ">=2026.5.3" } correctly, but linkOpenClawPeerDependencies() did not create the expected node_modules/openclaw symlink inside the installed plugin directory, so Node's resolver has nothing to walk to.
The result is total main-channel blackout: Telegram, Mission Control chat, and the gateway Control UI all stop receiving/sending messages even though the gateway process itself reports healthy.
Steps to reproduce
Install OpenClaw 2026.5.4 via Homebrew (/opt/homebrew/lib/node_modules/openclaw).
Have @openclaw/codex installed as a plugin into the default plugin npm root (~/.openclaw/npm/node_modules/@openclaw/codex, version 2026.5.3).
Restart the gateway.
Watch any main-session lane fail.
Expected behavior
Plugin install (or post-update reconciliation) should symlink the host openclaw package into the plugin's local node_modules/ per src/plugins/plugin-peer-link.ts → linkOpenClawPeerDependencies(). Main session lanes should boot normally.
Actual behavior
lane task error:
lane=session:agent:main:main durationMs=663
error="Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'openclaw'
imported from /Users/<user>/.openclaw/npm/node_modules/@openclaw/codex/dist/client-chGfNrq5.js"
Filesystem state immediately after the failure:
$ ls -la ~/.openclaw/npm/node_modules/@openclaw/codex/node_modules/
total 0
drwx------ 3 user staff 96 May 5 12:15 .
drwx------ 6 user staff 192 May 4 19:45 ..
drwx------ 2 user staff 64 May 5 10:32 .bin
# NOTE: no `openclaw` symlink — peer link was never written.
@openclaw/codex@2026.5.3package.json (relevant slice) — peer dep IS declared:
(Placing the link at the npm-root level rather than per-plugin works because Node walks ancestor node_modules directories. Per-plugin under @openclaw/codex/node_modules/openclaw works equally.)
To make the workaround survive openclaw update, we re-assert the symlink at the top of our recovery-check cron and a post-upgrade-verify script. With those guards, recovery is automatic within ~5 minutes after any future regression of the same shape.
Diagnosis
Looking at src/plugins/plugin-peer-link.ts:
consthostRoot=resolveOpenClawPackageRootSync({argv1: process.argv[1],moduleUrl: import.meta.url,cwd: process.cwd(),});if(!hostRoot){params.logger.warn?.("Could not locate openclaw package root to symlink peerDependencies; ...");return;}
resolveOpenClawPackageRootSync (in src/infra/openclaw-root.ts) walks argv1, moduleUrl, and cwd ancestors looking for a package.json whose name === "openclaw". Two plausible failure modes during plugin install in a Homebrew layout:
npm install runs in a child process whose argv1 is the npm CLI (not the OpenClaw binary), moduleUrl is inside npm's own dist, and cwd is the plugin npm root (~/.openclaw/npm) — none of those ancestor walks lead to /opt/homebrew/lib/node_modules/openclaw. hostRoot resolves to null, the warning is emitted, and the link is silently skipped.
An earlier successful link pointed to a previous Homebrew openclaw directory that was then removed during update, leaving a dangling/missing symlink that no later step rewrites.
Either way the install-time silent skip means a healthy update can leave the system in a hard-broken state with no obvious error other than lane crashes after restart.
Suggested fixes (any one would help; combining is best)
Make linkOpenClawPeerDependencies resilient to detached install contexts. When argv1/moduleUrl walks fail, fall back to:
an explicit OPENCLAW_HOST_ROOT env var the host can pre-set when shelling out to npm install.
Promote the silent skip to a hard failure when a plugin declares peerDependencies.openclaw and the host root can't be located. Today this is a logger.warn?. that nobody sees in the wild — that's how regressions like [Bug]: Matrix channel missing matrix-js-sdk after 2026.5.4 host npm update #77896 and this one ship without anyone noticing pre-release.
Re-run linkOpenClawPeerDependencies on gateway boot for every installed plugin that declares it (cheap idempotent symlink check), so the system self-heals after a Homebrew openclaw upgrade that moves/replaces the host root.
Add an installer-side smoke test that, after npm install completes for a plugin with peerDependencies.openclaw, asserts the link exists and points at a real directory before declaring install success.
Environment
OpenClaw: 2026.5.4 (325df3e)
Plugin: @openclaw/codex@2026.5.3
Node: v25.8.2
OS: macOS (Apple Silicon)
Install method: Homebrew global (/opt/homebrew/lib/node_modules/openclaw)
Plugin root: ~/.openclaw/npm/node_modules/
Gateway port: 18789 (loopback)
openclaw gateway status after the fix: Connectivity probe: ok
This appears to be a recurring class bug rather than a one-off — strong candidate for the "promote silent skip to hard failure + boot-time re-link" pattern above.
Bug type
Regression (worked before, now fails) — same packaging-regression family as #77896 (Matrix) and the cluster of closed issues #71484, #74692, #74899, #75032, #75056, #75206.
Summary
After updating to OpenClaw
2026.5.4on a Homebrew-managed install, every main-session lane crashes immediately withERR_MODULE_NOT_FOUNDbecause@openclaw/codex@2026.5.3cannot resolveopenclaw/plugin-sdk/*at runtime. The plugin declarespeerDependencies: { "openclaw": ">=2026.5.3" }correctly, butlinkOpenClawPeerDependencies()did not create the expectednode_modules/openclawsymlink inside the installed plugin directory, so Node's resolver has nothing to walk to.The result is total main-channel blackout: Telegram, Mission Control chat, and the gateway Control UI all stop receiving/sending messages even though the gateway process itself reports healthy.
Steps to reproduce
2026.5.4via Homebrew (/opt/homebrew/lib/node_modules/openclaw).@openclaw/codexinstalled as a plugin into the default plugin npm root (~/.openclaw/npm/node_modules/@openclaw/codex, version2026.5.3).Expected behavior
Plugin install (or post-update reconciliation) should symlink the host
openclawpackage into the plugin's localnode_modules/persrc/plugins/plugin-peer-link.ts → linkOpenClawPeerDependencies(). Main session lanes should boot normally.Actual behavior
Filesystem state immediately after the failure:
@openclaw/codex@2026.5.3package.json(relevant slice) — peer dep IS declared:{ "name": "@openclaw/codex", "version": "2026.5.3", "type": "module", "peerDependencies": { "openclaw": ">=2026.5.3" }, "devDependencies": { "@openclaw/plugin-sdk": "workspace:*" } }The codex plugin's compiled client imports the host SDK by sibling-package name, e.g.:
…which can only resolve if
openclawis reachable from the plugin'snode_moduleswalk. With the link missing, every import path explodes.Local workaround
Manually creating the link that
linkOpenClawPeerDependencies()was supposed to create restores everything immediately:ln -s /opt/homebrew/lib/node_modules/openclaw \ ~/.openclaw/npm/node_modules/openclaw openclaw gateway restart(Placing the link at the npm-root level rather than per-plugin works because Node walks ancestor
node_modulesdirectories. Per-plugin under@openclaw/codex/node_modules/openclawworks equally.)To make the workaround survive
openclaw update, we re-assert the symlink at the top of ourrecovery-checkcron and apost-upgrade-verifyscript. With those guards, recovery is automatic within ~5 minutes after any future regression of the same shape.Diagnosis
Looking at
src/plugins/plugin-peer-link.ts:resolveOpenClawPackageRootSync(insrc/infra/openclaw-root.ts) walksargv1,moduleUrl, andcwdancestors looking for apackage.jsonwhosename === "openclaw". Two plausible failure modes during plugin install in a Homebrew layout:npm installruns in a child process whoseargv1is thenpmCLI (not the OpenClaw binary),moduleUrlis insidenpm's own dist, andcwdis the plugin npm root (~/.openclaw/npm) — none of those ancestor walks lead to/opt/homebrew/lib/node_modules/openclaw.hostRootresolves tonull, the warning is emitted, and the link is silently skipped.Either way the install-time silent skip means a healthy update can leave the system in a hard-broken state with no obvious error other than lane crashes after restart.
Suggested fixes (any one would help; combining is best)
linkOpenClawPeerDependenciesresilient to detached install contexts. Whenargv1/moduleUrlwalks fail, fall back to:npm root -g+ Homebrew's/opt/homebrew/lib/node_modules,OPENCLAW_HOST_ROOTenv var the host can pre-set when shelling out tonpm install.peerDependencies.openclawand the host root can't be located. Today this is alogger.warn?.that nobody sees in the wild — that's how regressions like [Bug]: Matrix channel missing matrix-js-sdk after 2026.5.4 host npm update #77896 and this one ship without anyone noticing pre-release.linkOpenClawPeerDependencieson gateway boot for every installed plugin that declares it (cheap idempotent symlink check), so the system self-heals after a Homebrew openclaw upgrade that moves/replaces the host root.npm installcompletes for a plugin withpeerDependencies.openclaw, asserts the link exists and points at a real directory before declaring install success.Environment
2026.5.4 (325df3e)@openclaw/codex@2026.5.3v25.8.2/opt/homebrew/lib/node_modules/openclaw)~/.openclaw/npm/node_modules/18789(loopback)openclaw gateway statusafter the fix:Connectivity probe: okRelated
2026.5.4.bundled-deps installer omits the host openclaw package; Discord channel and 7 other extensions break withCannot find package 'openclaw' #71484, [Bug]: 2026.4.27 builtin memory can fail because plugin-runtime-deps snapshot misses sqlite-vec #74692, [Bug]: 2026.4.27 browser-control fails because plugin-runtime-deps cannot resolve ajv #74899, [Feature]: ExposeinstallBundledRuntimeDeps: false+ makeisolatedExecutionRootdefault for bundled plugin runtime deps #75032, Browser plugin fails to load on 2026.4.27: missingajvin plugin-runtime-deps #75056, Auto-update leaves stale chunk reference: conversation-runtime imports missing inbound.runtime-*.js → Telegram inbound dead until restart #75206 — sameERR_MODULE_NOT_FOUNDfamily.This appears to be a recurring class bug rather than a one-off — strong candidate for the "promote silent skip to hard failure + boot-time re-link" pattern above.