openclaw - ✅(Solved) Fix [Bug]: openclaw update uses npm from PATH instead of the npm that owns the installed global package [2 pull requests, 1 comments, 2 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#60150Fetched 2026-04-08 02:35:43
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×2labeled ×2closed ×1commented ×1

openclaw update resolves the current OpenClaw package root, but npm-based global update steps still use bare npm from PATH.

In mixed environments where OpenClaw is installed under one global npm prefix and a different npm is first on PATH, the updater targets the wrong global root.

This reproduces with a Homebrew-installed OpenClaw and nvm first on PATH.

Error Message

/opt/homebrew/bin/npm i -g openclaw@latest --no-fund --no-audit --loglevel=error

Root Cause

openclaw update resolves the current OpenClaw package root, but npm-based global update steps still use bare npm from PATH.

In mixed environments where OpenClaw is installed under one global npm prefix and a different npm is first on PATH, the updater targets the wrong global root.

This reproduces with a Homebrew-installed OpenClaw and nvm first on PATH.

Fix Action

Fixed

PR fix notes

PR #60153: Use owning npm prefix for global updates

Description (problem / solution / changelog)

Summary

  • Problem: openclaw update uses bare npm from PATH for npm-based global updates, even after it has already identified the installed OpenClaw package root.
  • Why it matters: in mixed global Node setups like Homebrew-installed OpenClaw with nvm first on PATH, the updater targets the wrong global npm root and can fail or update the wrong install context.
  • What changed: infer the owning npm prefix from the installed package root, prefer that npm executable for npm root -g and global install commands, and add regression coverage for the Homebrew-vs-nvm case.
  • What did NOT change (scope boundary): no changes to non-npm update flows, git checkout update logic, plugin install behavior, or daemon/runtime behavior outside the updater path.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause / Regression History (if applicable)

  • Root cause: updater logic treats manager = npm as “run npm from PATH” instead of resolving the npm executable associated with the installed package root being updated.
  • Missing detection / guardrail: no guardrail or test covered mixed global npm environments where the current OpenClaw install belongs to one prefix and PATH points at another npm.
  • Prior context (git blame, prior PR, issue, or refactor if known): unknown.
  • Why this regressed now: not confirmed as a recent regression; likely a latent bug that only shows up when users mix global Node toolchains.
  • If unknown, what was ruled out: ruled out a generic child-process spawn failure and ruled out a broken OpenClaw runtime install. The failure is isolated to updater package-manager resolution.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/infra/update-global.test.ts
  • Scenario the test should lock in: package root is under a Homebrew-style global npm prefix, while bare npm root -g resolves a different global root from PATH; updater should still choose the owning npm executable and correct package root.
  • Why this is the smallest reliable guardrail: the bug is in path/prefix resolution logic, so a focused unit test around manager/root/argv selection catches it without requiring full global install setup.
  • Existing test that already covers this (if any): existing tests covered manager detection and install argv generation, but not mixed-prefix npm environments.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • openclaw update now prefers the npm executable associated with the installed OpenClaw package root for npm-based global installs when it can infer that prefix.
  • This changes behavior only in mixed npm-prefix environments; behavior is unchanged for single-prefix installs.

Diagram (if applicable)

Before:
[openclaw update] -> [detect install root=/opt/homebrew/lib/node_modules/openclaw]
                 -> [run bare npm from PATH]
                 -> [npm root -g = ~/.nvm/.../node_modules]
                 -> [wrong global context]

After:
[openclaw update] -> [detect install root=/opt/homebrew/lib/node_modules/openclaw]
                 -> [infer owning prefix=/opt/homebrew]
                 -> [run /opt/homebrew/bin/npm]
                 -> [npm root -g = /opt/homebrew/lib/node_modules]
                 -> [correct global context]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (Yes)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:
    • The updater now chooses a more specific npm executable instead of bare npm from PATH when the installed package root clearly maps to an owning npm prefix. This reduces ambiguity rather than expanding execution scope. Fallback remains the existing behavior when no prefix can be inferred.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local global install
  • Model/provider: N/A
  • Integration/channel (if any): N/A
  • Relevant config (redacted):
    • installed package root: /opt/homebrew/lib/node_modules/openclaw
    • npm on PATH: /Users/jayesh/.nvm/versions/node/v23.6.0/bin/npm

Steps

  1. Install OpenClaw under Homebrew global npm so the package root is /opt/homebrew/lib/node_modules/openclaw.
  2. Put nvm npm first on PATH.
  3. Run:
    which npm
    npm root -g
    /opt/homebrew/bin/npm root -g
    openclaw update

Expected

  • Updater should use the npm executable that owns the installed OpenClaw package root.
  • For the example above, that means /opt/homebrew/bin/npm.

Actual

  • Updater uses bare npm from PATH, which resolves the nvm global root instead of the Homebrew global root.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Machine-level evidence from the repro environment:

{
  "pkgRoot": "/opt/homebrew/lib/node_modules/openclaw",
  "pathNpm": "/Users/jayesh/.nvm/versions/node/v23.6.0/bin/npm",
  "pathNpmRoot": "/Users/jayesh/.nvm/versions/node/v23.6.0/lib/node_modules",
  "selectedNpm": "/opt/homebrew/bin/npm",
  "selectedRoot": "/opt/homebrew/lib/node_modules",
  "oldUpdaterWouldMismatch": true,
  "patchedUpdaterMatches": true
}

Human Verification (required)

  • Verified scenarios:
    • confirmed mixed-prefix environment on a real macOS machine
    • confirmed bare npm root -g points at nvm while installed package root is under Homebrew
    • confirmed patched resolution logic selects /opt/homebrew/bin/npm
    • confirmed patched resolution logic maps back to /opt/homebrew/lib/node_modules/openclaw
  • Edge cases checked:
    • fallback behavior remains unchanged when no npm prefix can be inferred from package root
    • pnpm/bun argument generation remains unchanged
  • What you did not verify:
    • full repo test suite in this checkout
    • full end-to-end openclaw update execution from the patched repo build

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk:

    • inferring npm prefix from package-root shape could be too narrow and miss some valid npm global layouts
    • Mitigation:
      • only prefer the owning npm executable when the package root has the expected .../lib/node_modules/<pkg> shape and the derived npm binary exists; otherwise fall back to existing behavior
  • Risk:

    • package-manager resolution behavior changes for npm global installs
    • Mitigation:
      • change is scoped to npm installs only and regression coverage was added for the mixed-prefix scenario that triggered the bug

Changed files

  • src/cli/update-cli/update-command.ts (modified, +4/-4)
  • src/infra/update-global.test.ts (modified, +118/-1)
  • src/infra/update-global.ts (modified, +62/-7)
  • src/infra/update-runner.ts (modified, +3/-3)

PR #60172: fix(update): use manager binary associated with installed global root

Description (problem / solution / changelog)

Summary

  • derive the npm/pnpm executable from the installed package's global root instead of always using the bare PATH command
  • thread the resolved executable into global update and fallback update steps
  • add coverage for manager-command resolution and argv construction

Why

When OpenClaw is installed under one global prefix but a different npm is first on PATH, openclaw update should use the package owner's npm (for example /opt/homebrew/bin/npm) rather than the unrelated PATH npm.

Fixes #60150

Changed files

  • src/infra/update-global.test.ts (modified, +20/-4)
  • src/infra/update-global.ts (modified, +46/-5)
  • src/infra/update-runner.ts (modified, +4/-2)

Code Example

which npm
   npm root -g
   /opt/homebrew/bin/npm root -g


### Expected behavior

After determining the installed package root, npm-based global update operations should use the npm executable associated with that install prefix.

For example, with package root:

---

the updater should use:

---

instead of bare npm i -g ....

### Actual behavior

The updater uses bare npm from PATH, so it resolves the nvm global root instead of the Homebrew global root that owns the current OpenClaw install.

Example from my machine:

---

But the installed package being updated is:

---

### OpenClaw version

2026.4.2

### Operating system

macOS 26.3.1

### Install method

_No response_

### Model

openai

### Provider / routing chain

noene

### Additional provider/model setup details

_No response_

### Logs, screenshots, and evidence
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

openclaw update resolves the current OpenClaw package root, but npm-based global update steps still use bare npm from PATH.

In mixed environments where OpenClaw is installed under one global npm prefix and a different npm is first on PATH, the updater targets the wrong global root.

This reproduces with a Homebrew-installed OpenClaw and nvm first on PATH.

Environment

  • macOS
  • OpenClaw: 2026.4.2
  • installed package root: /opt/homebrew/lib/node_modules/openclaw
  • npm on PATH: /Users/jayesh/.nvm/versions/node/v23.6.0/bin/npm

Steps to reproduce

  1. Install OpenClaw under Homebrew global npm so the package lives at: /opt/homebrew/lib/node_modules/openclaw
  2. Put nvm npm first on PATH
  3. Confirm the mismatch:
    which npm
    npm root -g
    /opt/homebrew/bin/npm root -g

Expected behavior

After determining the installed package root, npm-based global update operations should use the npm executable associated with that install prefix.

For example, with package root:

/opt/homebrew/lib/node_modules/openclaw

the updater should use:

/opt/homebrew/bin/npm i -g openclaw@latest --no-fund --no-audit --loglevel=error

instead of bare npm i -g ....

Actual behavior

The updater uses bare npm from PATH, so it resolves the nvm global root instead of the Homebrew global root that owns the current OpenClaw install.

Example from my machine:

npm root -g -> /Users/jayesh/.nvm/versions/node/v23.6.0/lib/node_modules
/opt/homebrew/bin/npm root -g -> /opt/homebrew/lib/node_modules

But the installed package being updated is:

/opt/homebrew/lib/node_modules/openclaw

OpenClaw version

2026.4.2

Operating system

macOS 26.3.1

Install method

No response

Model

openai

Provider / routing chain

noene

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

The updater should use the npm executable associated with the installed package root prefix instead of the bare npm from PATH.

Guidance

  • Identify the correct npm executable associated with the installed package root prefix, e.g., /opt/homebrew/bin/npm.
  • Update the openclaw update command to use the correct npm executable, e.g., /opt/homebrew/bin/npm i -g openclaw@latest --no-fund --no-audit --loglevel=error.
  • Verify the fix by checking the output of npm root -g and ensuring it matches the expected package root.
  • Consider modifying the openclaw update script to dynamically determine the correct npm executable based on the installed package root.

Example

# Determine the correct npm executable
CORRECT_NPM=$(dirname $(which openclaw))/../bin/npm

# Update the package using the correct npm executable
$CORRECT_NPM i -g openclaw@latest --no-fund --no-audit --loglevel=error

Notes

This solution assumes that the openclaw update command can be modified to use the correct npm executable. If this is not possible, alternative solutions may be necessary.

Recommendation

Apply a workaround by modifying the openclaw update command to use the correct npm executable, as this will ensure that the update operation targets the correct global root.

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

After determining the installed package root, npm-based global update operations should use the npm executable associated with that install prefix.

For example, with package root:

/opt/homebrew/lib/node_modules/openclaw

the updater should use:

/opt/homebrew/bin/npm i -g openclaw@latest --no-fund --no-audit --loglevel=error

instead of bare npm i -g ....

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 - ✅(Solved) Fix [Bug]: openclaw update uses npm from PATH instead of the npm that owns the installed global package [2 pull requests, 1 comments, 2 participants]