openclaw - 💡(How to fix) Fix Matrix dependency bootstrap can delete global OpenClaw install by running npm install from global node_modules

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…

OpenClaw 2026.5.7 appears to run the Matrix dependency bootstrap with cwd set to the global npm node_modules directory.

On macOS/Homebrew global npm installs, this can resolve to:

/opt/homebrew/lib/node_modules

OpenClaw then runs:

npm install --omit=dev --silent

Because npm is invoked from a directory named node_modules, npm treats the parent directory (/opt/homebrew/lib) as the project root. If that parent directory has no package.json / dependency graph, npm reifies an empty project, retires existing global packages, removes them as extraneous, and writes empty lockfiles.

The practical impact is severe: this can remove the globally installed openclaw package directory while leaving the openclaw CLI symlink dangling, breaking the OpenClaw CLI on the machine.

Error Message

2026-05-11T17:38:57.791+03:00 Error: Matrix dependency install failed.

Root Cause

Because npm is invoked from a directory named node_modules, npm treats the parent directory (/opt/homebrew/lib) as the project root. If that parent directory has no package.json / dependency graph, npm reifies an empty project, retires existing global packages, removes them as extraneous, and writes empty lockfiles.

Code Example

/opt/homebrew/lib/node_modules

---

npm install --omit=dev --silent

---

2026-05-11T17:38:55.712+03:00
matrix: installing dependencies via npm (/opt/homebrew/lib/node_modules)...

---

2026-05-11T17:38:57.791+03:00
Error: Matrix dependency install failed.

---

/opt/homebrew/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs
/opt/homebrew/bin/codex -> ../lib/node_modules/@openai/codex/bin/codex.js

---

/opt/homebrew/lib/node_modules/.bin
/opt/homebrew/lib/node_modules/.package-lock.json
/opt/homebrew/lib/node_modules/@openai

---

{
  "name": "lib",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {}
}

---

function resolvePluginRoot() {
  const currentDir = path.dirname(fileURLToPath(import.meta.url));
  return path.resolve(currentDir, "..", "..");
}

---

/opt/homebrew/lib/node_modules/openclaw/dist/

---

/opt/homebrew/lib/node_modules

---

repro="$(mktemp -d /tmp/npm-node-modules-reify.XXXXXX)"
mkdir -p "$repro/lib/node_modules/openclaw" "$repro/lib/node_modules/@openai/codex"

printf '{"name":"openclaw","version":"1.0.0","bin":{"openclaw":"openclaw.mjs"}}\n' \
  > "$repro/lib/node_modules/openclaw/package.json"

printf '#!/usr/bin/env node\n' \
  > "$repro/lib/node_modules/openclaw/openclaw.mjs"

printf '{"name":"@openai/codex","version":"1.0.0"}\n' \
  > "$repro/lib/node_modules/@openai/codex/package.json"

cd "$repro/lib/node_modules"
npm install --omit=dev --loglevel=notice
find "$repro/lib" -maxdepth 4 -print | sort
RAW_BUFFERClick to expand / collapse

Matrix dependency bootstrap can delete global OpenClaw install by running npm install from global node_modules

Summary

OpenClaw 2026.5.7 appears to run the Matrix dependency bootstrap with cwd set to the global npm node_modules directory.

On macOS/Homebrew global npm installs, this can resolve to:

/opt/homebrew/lib/node_modules

OpenClaw then runs:

npm install --omit=dev --silent

Because npm is invoked from a directory named node_modules, npm treats the parent directory (/opt/homebrew/lib) as the project root. If that parent directory has no package.json / dependency graph, npm reifies an empty project, retires existing global packages, removes them as extraneous, and writes empty lockfiles.

The practical impact is severe: this can remove the globally installed openclaw package directory while leaving the openclaw CLI symlink dangling, breaking the OpenClaw CLI on the machine.

Environment

  • macOS 26.2, arm64
  • Node v24.15.0
  • npm 11.12.1
  • OpenClaw 2026.5.7
  • Homebrew prefix: /opt/homebrew
  • Global npm root: /opt/homebrew/lib/node_modules

Evidence

OpenClaw log:

2026-05-11T17:38:55.712+03:00
matrix: installing dependencies via npm (/opt/homebrew/lib/node_modules)...

Immediately after:

2026-05-11T17:38:57.791+03:00
Error: Matrix dependency install failed.

Afterward, these symlinks were left dangling:

/opt/homebrew/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs
/opt/homebrew/bin/codex -> ../lib/node_modules/@openai/codex/bin/codex.js

The global npm root was reduced to essentially:

/opt/homebrew/lib/node_modules/.bin
/opt/homebrew/lib/node_modules/.package-lock.json
/opt/homebrew/lib/node_modules/@openai

Both lockfiles were created at the failure time and contained:

{
  "name": "lib",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {}
}

Suspected Root Cause

Recovered bundled code from the OpenClaw 2026.5.7 Matrix dependency bootstrap appears to resolve the plugin root like this:

function resolvePluginRoot() {
  const currentDir = path.dirname(fileURLToPath(import.meta.url));
  return path.resolve(currentDir, "..", "..");
}

When bundled under:

/opt/homebrew/lib/node_modules/openclaw/dist/

that resolves to:

/opt/homebrew/lib/node_modules

The bootstrap then runs npm install with that value as cwd.

Minimal Reproduction Of npm Behavior

repro="$(mktemp -d /tmp/npm-node-modules-reify.XXXXXX)"
mkdir -p "$repro/lib/node_modules/openclaw" "$repro/lib/node_modules/@openai/codex"

printf '{"name":"openclaw","version":"1.0.0","bin":{"openclaw":"openclaw.mjs"}}\n' \
  > "$repro/lib/node_modules/openclaw/package.json"

printf '#!/usr/bin/env node\n' \
  > "$repro/lib/node_modules/openclaw/openclaw.mjs"

printf '{"name":"@openai/codex","version":"1.0.0"}\n' \
  > "$repro/lib/node_modules/@openai/codex/package.json"

cd "$repro/lib/node_modules"
npm install --omit=dev --loglevel=notice
find "$repro/lib" -maxdepth 4 -print | sort

Observed result:

  • npm errors with ENOENT for $repro/lib/package.json
  • openclaw is removed
  • @openai/codex is removed
  • $repro/lib/package-lock.json is created
  • $repro/lib/node_modules/.package-lock.json is created
  • the generated lockfiles contain an empty package graph named "lib"

Verbose npm logs show npm first marks packages as retired / moves them into hidden paths like .openclaw-*, then removes / unlinks them.

Suggested Fix

  • Do not run plugin dependency installation with cwd set to a global node_modules root.
  • Resolve the Matrix dependency root to the actual Matrix extension package directory or to a dedicated dependency directory.
  • Add a hard guard: refuse to run npm if cwd ends in /node_modules and has no local package.json.
  • Consider using a state-local dependency path such as ~/.openclaw/plugin-deps/matrix.
  • Surface npm stderr/stdout in the OpenClaw error so the underlying npm failure is visible even when --silent is used.

Impact

This can break the OpenClaw CLI by removing the global openclaw package directory while leaving /opt/homebrew/bin/openclaw as a dangling symlink. On Homebrew-based global npm installs, a Matrix dependency bootstrap failure can therefore require manual repair or reinstallation of OpenClaw.

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

openclaw - 💡(How to fix) Fix Matrix dependency bootstrap can delete global OpenClaw install by running npm install from global node_modules