openclaw - ✅(Solved) Fix [Bug]: gateway install generates service env with PATH missing the openclaw binary's directory (breaks npm-global installs) [1 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#84201Fetched 2026-05-20 03:42:48
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
1
Timeline (top)
labeled ×5commented ×1cross-referenced ×1

openclaw gateway install generates ~/.openclaw/service-env/<label>.env with a hardcoded PATH that does not include the directory containing the openclaw binary, so child processes spawned by the gateway (e.g. agent shells) cannot find openclaw on PATH. Reproduced on 2026.5.18 with an npm-global install at ~/.npm-global/bin/openclaw.

Root Cause

Impact and severity

  • Affected: any user whose openclaw binary lives outside the installer's hardcoded path list — npm-global installs to a user prefix, pnpm-global, volta, asdf, fnm, and other non-homebrew layouts.
  • Severity: Medium. Agents cannot invoke openclaw as a shell tool from within their own sessions, which silently disables any agent workflow that calls back into the CLI (skills, hooks, recovery flows). The gateway itself stays healthy because it was launched with an absolute path.
  • Frequency: Deterministic — every regeneration of the service env file reproduces it.
  • Consequence: Agent reports openclaw: command not found and any CLI-dependent capability degrades silently.

Fix Action

Fix / Workaround

Workaround: edit the generated env file to prepend the openclaw binary's directory to PATH:

export PATH='/Users/<user>/.npm-global/bin:/opt/homebrew/opt/node/bin:...'

Then openclaw gateway restart. This holds until the next openclaw gateway install --force (which the 5.7 update suggested as a recovery step), at which point the file is regenerated and the override returns.

Suggested fix: in the service-env generator, derive the openclaw binary's directory from path.dirname(process.execPath) (or from which('openclaw') if process.execPath points to node rather than the wrapper) and prepend it to the default PATH list. Optionally also merge in the installer's own process.env.PATH so that whatever the user's shell saw is preserved.

PR fix notes

PR #84207: fix(installer): keep openclaw bin dir on service PATH for prefix installs

Description (problem / solution / changelog)

Summary

Fixes #84201. The macOS service env file generated by openclaw gateway install restricts PATH to system+homebrew directories only. For installs whose binary lives elsewhere (npm-global, pnpm-global, volta, etc.), openclaw is unreachable from the supervised environment — gateway children (agent shells, hooks) that try to call back into the CLI silently fail with "command not found." The LaunchAgent's inherited PATH does contain the right directory, but the env-wrapper sources the generated env file before exec, so the narrower PATH wins.

This PR detects the install-time openclaw bin directory by walking the install process's PATH for the first segment containing an executable named openclaw, and includes it in extraPathDirs alongside the existing node bin directory.

This is the same shape of bug as #77416 / PR #77421 (installer assumed a layout that held for some installs but not others). The intentionally narrow darwin service PATH posture from getMinimalServicePathParts in src/daemon/service-env.ts is preserved — we only add the one directory we know the gateway needs to function.

What changed

  • src/commands/daemon-install-plan.shared.ts:
    • new resolveOpenclawBinDir(env, platform, existsSync) helper that walks PATH for the first dir containing openclaw (or openclaw.cmd/.exe/.bat on win32)
    • new resolveDaemonExtraPathDirs({nodePath, env, platform}) helper that combines the openclaw bin dir with the existing node bin dir, deduped, in priority order
  • src/commands/daemon-install-helpers.ts: gateway install plan now uses resolveDaemonExtraPathDirs instead of resolveDaemonNodeBinDir alone
  • src/commands/node-daemon-install-helpers.ts: same fix for the node-host service install plan
  • src/commands/daemon-install-plan.shared.test.ts: regression tests for both helpers across darwin/linux/win32
  • CHANGELOG.md: entry under Unreleased > Fixes

Test plan

  • pnpm vitest run src/commands/daemon-install-plan.shared.test.ts — 12/12 pass (10 new)
  • pnpm vitest run src/commands/daemon-install-helpers.test.ts src/commands/node-daemon-install-helpers.test.ts — 33/33 pass
  • pnpm tsgo:core clean
  • pnpm tsgo:core:test clean
  • pnpm lint:core — 0 warnings, 0 errors

Human-run real behavior proof

Reproduced on my own machine (openclaw 2026.5.18, macOS 26.2 arm64, npm-global install at ~/.npm-global/bin/openclaw):

$ grep '^export PATH=' ~/.openclaw/service-env/ai.openclaw.gateway.env
export PATH='/opt/homebrew/opt/node/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
$ which openclaw
/Users/magpie/.npm-global/bin/openclaw

~/.npm-global/bin was missing from the supervised PATH. The gateway's main agent reported openclaw: command not found from its shell tool. Manually prepending ~/.npm-global/bin to the env file's PATH= line and restarting the gateway restored CLI reachability for child processes. With this fix, extraPathDirs would include ~/.npm-global/bin automatically because that's the directory where openclaw is found on PATH at install time.

AI-assisted

  • Drafted with Claude (Opus) based on direct investigation of the affected machine — the agent read the running gateway plist, traced ~/.openclaw/service-env/<label>.env, the wrapper script, and the install-time helpers (daemon-install-helpers.ts, service-env.ts) before writing any code.
  • Real-machine repro and workaround applied & verified before the PR was written. Tests are supplemental.
  • Codex review (codex review --base origin/main) — to be run by the reporter before requesting review.
  • Confirmed I understand what the code does. The fix is narrow and additive: a new helper walks the install-time PATH for the openclaw binary, and the existing extraPathDirs channel feeds it into buildMinimalServicePathgetMinimalServicePathParts's extraDirs slot, which is positioned ahead of system dirs but does not relax the darwin user-bin exclusion.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/commands/daemon-install-helpers.ts (modified, +2/-2)
  • src/commands/daemon-install-plan.shared.test.ts (modified, +95/-0)
  • src/commands/daemon-install-plan.shared.ts (modified, +69/-0)
  • src/commands/node-daemon-install-helpers.ts (modified, +4/-3)

Code Example

export PATH='/opt/homebrew/opt/node/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'

---

$ which openclaw
/Users/magpie/.npm-global/bin/openclaw
$ ls -l /Users/magpie/.npm-global/bin/openclaw
lrwxr-xr-x  1 magpie  staff  41 May 18 19:03 /Users/magpie/.npm-global/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs

---

inherited environment = {
    PATH => /Users/magpie/.npm-global/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
}

---

$ grep '^export PATH=' ~/.openclaw/service-env/ai.openclaw.gateway.env
export PATH='/opt/homebrew/opt/node/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'

---

#!/bin/sh
set -eu
env_file="$1"
shift
if [ -f "$env_file" ]; then
  . "$env_file"
fi
exec "$@"

---

export PATH='/Users/<user>/.npm-global/bin:/opt/homebrew/opt/node/bin:...'
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

openclaw gateway install generates ~/.openclaw/service-env/<label>.env with a hardcoded PATH that does not include the directory containing the openclaw binary, so child processes spawned by the gateway (e.g. agent shells) cannot find openclaw on PATH. Reproduced on 2026.5.18 with an npm-global install at ~/.npm-global/bin/openclaw.

Steps to reproduce

  1. Install OpenClaw to a non-homebrew prefix: npm config set prefix ~/.npm-global && npm install -g openclaw so the binary lives at ~/.npm-global/bin/openclaw.
  2. Run openclaw gateway install --force (or let an openclaw update regenerate the service env, as 2026.5.12 → 2026.5.18 did on this machine).
  3. Inspect the generated env file: grep '^export PATH=' ~/.openclaw/service-env/ai.openclaw.gateway.env.
  4. From an agent session (or any gateway-spawned shell), run which openclaw.

Expected behavior

The generated PATH in the service env file should include the directory of the openclaw binary that performed the install — i.e. path.dirname(process.execPath) or equivalent. Child processes of the gateway should be able to invoke openclaw from the shell.

Actual behavior

The generated PATH is hardcoded to homebrew + system paths only:

export PATH='/opt/homebrew/opt/node/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'

/Users/<user>/.npm-global/bin (where the active openclaw binary lives) is not in the list. Agent child processes report openclaw: command not found. The LaunchAgent's inherited environment does include ~/.npm-global/bin — but the wrapper script (ai.openclaw.gateway-env-wrapper.sh) sources the generated env file, whose export PATH=... overrides the inherited value before execing node.

OpenClaw version

2026.5.18 (50a2481)

Operating system

macOS 26.2 (arm64)

Install method

npm global (npm install -g openclaw with prefix ~/.npm-global)

Model

openai/gpt-5.5 (not relevant to this bug — issue is in installer/service-env generation, not the agent runtime)

Provider / routing chain

openclaw -> openai (not relevant to this bug)

Logs, screenshots, and evidence

which openclaw from the user shell:

$ which openclaw
/Users/magpie/.npm-global/bin/openclaw
$ ls -l /Users/magpie/.npm-global/bin/openclaw
lrwxr-xr-x  1 magpie  staff  41 May 18 19:03 /Users/magpie/.npm-global/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs

launchctl print gui/502/ai.openclaw.gateway shows the LaunchAgent inherited PATH contains the right directory:

inherited environment = {
    PATH => /Users/magpie/.npm-global/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
}

But the generated service env file overrides it:

$ grep '^export PATH=' ~/.openclaw/service-env/ai.openclaw.gateway.env
export PATH='/opt/homebrew/opt/node/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'

The wrapper script sources that file and then execs the gateway:

#!/bin/sh
set -eu
env_file="$1"
shift
if [ -f "$env_file" ]; then
  . "$env_file"
fi
exec "$@"

So node (and every child it spawns) inherits the narrower PATH, missing ~/.npm-global/bin.

Impact and severity

  • Affected: any user whose openclaw binary lives outside the installer's hardcoded path list — npm-global installs to a user prefix, pnpm-global, volta, asdf, fnm, and other non-homebrew layouts.
  • Severity: Medium. Agents cannot invoke openclaw as a shell tool from within their own sessions, which silently disables any agent workflow that calls back into the CLI (skills, hooks, recovery flows). The gateway itself stays healthy because it was launched with an absolute path.
  • Frequency: Deterministic — every regeneration of the service env file reproduces it.
  • Consequence: Agent reports openclaw: command not found and any CLI-dependent capability degrades silently.

Additional information

Workaround: edit the generated env file to prepend the openclaw binary's directory to PATH:

export PATH='/Users/<user>/.npm-global/bin:/opt/homebrew/opt/node/bin:...'

Then openclaw gateway restart. This holds until the next openclaw gateway install --force (which the 5.7 update suggested as a recovery step), at which point the file is regenerated and the override returns.

Suggested fix: in the service-env generator, derive the openclaw binary's directory from path.dirname(process.execPath) (or from which('openclaw') if process.execPath points to node rather than the wrapper) and prepend it to the default PATH list. Optionally also merge in the installer's own process.env.PATH so that whatever the user's shell saw is preserved.

This is the same shape of bug as #77416 / PR #77421 (channel contract API resolver assumed a layout that held for some installs but not others). The installer is making layout assumptions that hold for homebrew-installed openclaw but not for npm-global or other prefix-based installs.


AI-assisted: this report was drafted by Claude (Anthropic) based on direct investigation of the user's local install. All evidence (file paths, launchctl print output, env file contents, wrapper script contents) was read from the user's machine and verified before filing. Reporter (mogglemoss) reviewed and approved before submission.

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

The generated PATH in the service env file should include the directory of the openclaw binary that performed the install — i.e. path.dirname(process.execPath) or equivalent. Child processes of the gateway should be able to invoke openclaw from the shell.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING