Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
openclaw plugins install runs npm install in the plugin directory, and npm 7+'s auto-install-peers behavior installs openclaw itself as a nested dependency of the plugin, dragging in openclaw's entire transitive tree (lancedb, slack, lark, baileys, jimp, pdfjs, koffi, napi-rs, etc.) and adding a ~15-second module-resolution tax to every CLI subcommand.
Steps to reproduce
- Install OpenClaw 2026.4.15 globally (pnpm/npm — both reproduce).
- Run
openclaw plugins install @martian-engineering/lossless-claw (any plugin whose package.json declares peerDependencies: { "openclaw": "*" } reproduces this).
du -sh ~/.openclaw/extensions/lossless-claw/node_modules/ → 817 MB.
du -sh ~/.openclaw/extensions/lossless-claw/node_modules/openclaw/ → 97 MB (a nested second copy of openclaw itself).
time openclaw config get meta → ~23s wall, ~32s user CPU. Trivial command, ~15s of which is module-resolution / dlopen overhead from the nested openclaw and its native deps.
- Quarantine just the nested copy:
mv ~/.openclaw/extensions/lossless-claw/node_modules/openclaw /tmp/.
- Re-run
time openclaw config get meta → 7.6s (matches the time when the entire extension is hidden — proving the nested openclaw was the entire 15s tax).
Expected behavior
peerDependencies on openclaw should not cause a second copy of openclaw to be installed inside the plugin's node_modules/. The host CLI is already openclaw and should satisfy the peer at load time. Either:
- Install plugins with
--omit=peer (or --legacy-peer-deps) so npm 7+ doesn't auto-install missing peers, or
- Symlink/inject the running openclaw into the plugin's
node_modules/openclaw so npm sees it as already satisfied, or
- Configure Node's module resolution so
import 'openclaw' from the plugin resolves to the host install path.
Devastating-sized native deps (lancedb, koffi, jimp, napi-rs, pdfjs) should never end up in a plugin install just because the plugin peer-depends on openclaw.
Actual behavior
~/.openclaw/extensions/<plugin>/node_modules/ ends up at hundreds of MBs with a self-referential nested openclaw and its full chat/vector/native-binding dep tree. Every subcommand pays ~15s of import + dlopen overhead. Plugin authors and end-users have no signal anything is wrong — the plugin loads and works, it's just slow on every invocation.
Top offenders observed in ~/.openclaw/extensions/lossless-claw/node_modules/ (lossless-claw itself only declares 4 runtime deps totaling ~16 MB):
| Module |
Size |
Reachable from? |
openclaw/ |
97 MB |
(the nested copy itself) |
@lancedb/ |
92 MB |
nested openclaw only |
@jimp/ |
88 MB |
nested openclaw only |
pdfjs-dist/ |
40 MB |
nested openclaw only |
koffi/ |
28 MB |
nested openclaw only |
@napi-rs/ |
25 MB |
nested openclaw only |
@larksuiteoapi/ |
24 MB |
nested openclaw only |
typescript/ |
23 MB |
dev-dep leak |
@img/ |
16 MB |
nested openclaw only |
openclaw plugins inspect lossless-claw reports the install as Source: npm, Spec: @martian-engineering/lossless-claw@0.9.2, confirming this came from openclaw plugins install, not a manual drop.
OpenClaw version
2026.4.15 (041266a)
Operating system
macOS 26.3.1 (arm64), Node 25.8.0
Install method
npm global (package manager: pnpm per openclaw status)
Model
openai-codex/gpt-5.4
Provider / routing chain
openclaw -> openai-codex
Additional provider/model setup details
Not relevant — the bug is in openclaw plugins install, independent of model/provider routing.
Logs, screenshots, and evidence
$ cat ~/.openclaw/extensions/lossless-claw/package.json | jq '.dependencies, .peerDependencies, .scripts.build'
{
"@mariozechner/pi-agent-core": "0.66.1",
"@mariozechner/pi-ai": "0.66.1",
"@mariozechner/pi-coding-agent": "0.66.1",
"@sinclair/typebox": "0.34.48"
}
{ "openclaw": "*" }
"esbuild index.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/index.js --external:openclaw --external:\"@mariozechner/*\" --minify-whitespace"
# Direct deps total ~16 MB. Actual node_modules:
$ du -sh ~/.openclaw/extensions/lossless-claw/node_modules/
817M
# The nested openclaw is a full copy of the host install:
$ du -sh ~/.openclaw/extensions/lossless-claw/node_modules/openclaw/
97M
# Timing comparison:
$ time openclaw config get meta > /dev/null
openclaw config get meta > /dev/null 31.11s user 2.15s system 143% cpu 23.240 total
$ mv ~/.openclaw/extensions/lossless-claw/node_modules/openclaw /tmp/quarantine/
$ time openclaw config get meta > /dev/null
openclaw config get meta > /dev/null 11.03s user 0.57s system 152% cpu 7.592 total
# (Same 7.6s as when the entire extension dir is hidden — so the nested openclaw is the *entire* tax.)
Impact and severity
- Affected: every plugin that declares
peerDependencies: { "openclaw": "*" } (or any version range) installed via openclaw plugins install on a machine with npm 7+.
- Severity: Medium. Plugins still load and work; UX is significantly degraded. ~15s added latency on every CLI invocation, plus ~700 MB of unneeded disk per such plugin.
- Frequency: Always reproduces on the configurations above. 3/3 timed
openclaw status runs were ~19s wall (vs. ~4s expected); 3/3 trivial commands like config get meta were ~23s.
- Consequence: CLI feels broken, users assume openclaw itself is slow, plugin authors get blamed for slow startup that's not their fault. Plus large unnecessary disk consumption per plugin.
Additional information
This is the unintended consequence of the fix for #53517 ("openclaw plugins install does not install peer dependency"). That fix made openclaw plugins install properly run npm install, which under npm 7+ auto-installs peer deps. For plugins whose peer is openclaw itself, that means installing a fresh second copy of the host CLI as a child of the plugin — recursive in spirit, since openclaw is what's installing the plugin.
Suggested fix: openclaw plugins install should pass --omit=peer to npm (and resolve the host's openclaw via symlink, hoist, or NODE_PATH for plugins that genuinely need to import 'openclaw' at runtime). Probably also --omit=dev — TypeScript leaked in here as a 23 MB devDep.
Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
openclaw plugins installrunsnpm installin the plugin directory, and npm 7+'s auto-install-peers behavior installsopenclawitself as a nested dependency of the plugin, dragging in openclaw's entire transitive tree (lancedb, slack, lark, baileys, jimp, pdfjs, koffi, napi-rs, etc.) and adding a ~15-second module-resolution tax to every CLI subcommand.Steps to reproduce
openclaw plugins install @martian-engineering/lossless-claw(any plugin whosepackage.jsondeclarespeerDependencies: { "openclaw": "*" }reproduces this).du -sh ~/.openclaw/extensions/lossless-claw/node_modules/→ 817 MB.du -sh ~/.openclaw/extensions/lossless-claw/node_modules/openclaw/→ 97 MB (a nested second copy of openclaw itself).time openclaw config get meta→ ~23s wall, ~32s user CPU. Trivial command, ~15s of which is module-resolution / dlopen overhead from the nested openclaw and its native deps.mv ~/.openclaw/extensions/lossless-claw/node_modules/openclaw /tmp/.time openclaw config get meta→ 7.6s (matches the time when the entire extension is hidden — proving the nested openclaw was the entire 15s tax).Expected behavior
peerDependenciesonopenclawshould not cause a second copy ofopenclawto be installed inside the plugin'snode_modules/. The host CLI is already openclaw and should satisfy the peer at load time. Either:--omit=peer(or--legacy-peer-deps) so npm 7+ doesn't auto-install missing peers, ornode_modules/openclawso npm sees it as already satisfied, orimport 'openclaw'from the plugin resolves to the host install path.Devastating-sized native deps (lancedb, koffi, jimp, napi-rs, pdfjs) should never end up in a plugin install just because the plugin peer-depends on openclaw.
Actual behavior
~/.openclaw/extensions/<plugin>/node_modules/ends up at hundreds of MBs with a self-referential nested openclaw and its full chat/vector/native-binding dep tree. Every subcommand pays ~15s of import + dlopen overhead. Plugin authors and end-users have no signal anything is wrong — the plugin loads and works, it's just slow on every invocation.Top offenders observed in
~/.openclaw/extensions/lossless-claw/node_modules/(lossless-claw itself only declares 4 runtime deps totaling ~16 MB):openclaw/@lancedb/@jimp/pdfjs-dist/koffi/@napi-rs/@larksuiteoapi/typescript/@img/openclaw plugins inspect lossless-clawreports the install asSource: npm,Spec: @martian-engineering/lossless-claw@0.9.2, confirming this came fromopenclaw plugins install, not a manual drop.OpenClaw version
2026.4.15 (041266a)
Operating system
macOS 26.3.1 (arm64), Node 25.8.0
Install method
npm global (package manager: pnpm per
openclaw status)Model
openai-codex/gpt-5.4
Provider / routing chain
openclaw -> openai-codex
Additional provider/model setup details
Not relevant — the bug is in
openclaw plugins install, independent of model/provider routing.Logs, screenshots, and evidence
Impact and severity
peerDependencies: { "openclaw": "*" }(or any version range) installed viaopenclaw plugins installon a machine with npm 7+.openclaw statusruns were ~19s wall (vs. ~4s expected); 3/3 trivial commands likeconfig get metawere ~23s.Additional information
This is the unintended consequence of the fix for #53517 ("openclaw plugins install does not install peer dependency"). That fix made
openclaw plugins installproperly runnpm install, which under npm 7+ auto-installs peer deps. For plugins whose peer is openclaw itself, that means installing a fresh second copy of the host CLI as a child of the plugin — recursive in spirit, since openclaw is what's installing the plugin.Suggested fix:
openclaw plugins installshould pass--omit=peerto npm (and resolve the host's openclaw via symlink, hoist, orNODE_PATHfor plugins that genuinely need toimport 'openclaw'at runtime). Probably also--omit=dev— TypeScript leaked in here as a 23 MB devDep.