#18112: fix(daemon): gateway install on macOS ignores fnm/nvm node (#18090)
gateway
commands
stale
size: M
trusted-contributor
Cluster:
Node and macOS Enhancements
## Summary
`openclaw gateway install` on macOS hardcodes `/opt/homebrew/bin/node` in the launchd plist even when the user runs the command under fnm/nvm. The node that's actually running the install gets ignored.
Closes #18090
lobster-biscuit
## Root Cause
`resolvePreferredNodePath` in `runtime-paths.ts` only checks hardcoded system candidates (`/opt/homebrew/bin/node`, `/usr/local/bin/node`, `/usr/bin/node`). It never looks at `process.execPath` — the node actually executing the install command. So fnm/nvm users always get Homebrew's node in their plist.
## Changes
- Before: plist always uses the first accessible system node candidate, regardless of what node is running the CLI
- After: checks `process.execPath` first — if it's a supported version (22+), uses it; otherwise falls back to system node as before
Files touched:
- `src/daemon/runtime-paths.ts` — added `processExecPath` param, version-check it before system fallback
- `src/commands/daemon-install-helpers.ts` — pass `process.execPath` to the resolver
- `src/commands/node-daemon-install-helpers.ts` — same
Note: the second half of #18090 (extending version manager PATH dirs to macOS in `service-env.ts`) is already covered by open PR #4709, so I left that alone.
## Tests
- `runtime-paths.test.ts` — 5 new tests covering: fnm node preferred over system node, fallback when execPath not provided, fallback when execPath version is too old, fallback when version check throws, fallback on empty version string, runtime !== "node" short-circuit, Linux platform behavior. All fail before fix, pass after.
- `pnpm build && pnpm check` pass
- All 89 daemon directory tests pass
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed `openclaw gateway install` on macOS to respect the Node.js binary currently executing the install command (from fnm/nvm) instead of always defaulting to Homebrew's system node. The fix checks `process.execPath` first and only falls back to system node candidates if the executing node is unsupported or not provided.
Key changes:
- Added `processExecPath` parameter to `resolvePreferredNodePath` function
- Version-checks `process.execPath` before falling back to system node paths
- Passes `process.execPath` from install commands to the resolver
- Added comprehensive test coverage (7 new tests) covering happy path, fallbacks, error cases, and Linux platform
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is straightforward, well-tested with 7 new comprehensive test cases, follows existing patterns in the codebase, and gracefully handles edge cases (missing files, unsupported versions, error conditions). The fix is minimal and focused, adding only the necessary logic to check `process.execPath` before falling back to system node
- No files require special attention
<sub>Last reviewed commit: 28b8219</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#6064: fix(daemon): prefer bundled node from install-cli.sh over system node
by joyshmitz · 2026-02-01
86.1%
#20584: fix: use stable Homebrew symlink for daemon node path
by mwfj · 2026-02-19
81.7%
#22929: Fix NODE_EXTRA_CA_CERTS missing from LaunchAgent environment on macOS
by Clawborn · 2026-02-21
81.3%
#12804: fix(daemon): use wrapper script for pnpm global installs in service...
by odinho · 2026-02-09
81.2%
#4709: fix(daemon): include user bin dirs in macOS LaunchAgent PATH
by ekson73 · 2026-01-30
79.1%
#15475: fix(update): Handle Homebrew+Node Cellar path mismatch
by brandonwise · 2026-02-13
78.1%
#20390: fix(daemon): fall back to /tmp for launchd logs on removable volumes
by lemoz · 2026-02-18
78.0%
#17929: fix(skills): augment PATH with /etc/paths on macOS for binary detec...
by lailoo · 2026-02-16
77.7%
#22341: fix(status): detect node-only mode and show remote gateway info
by therk · 2026-02-21
77.7%
#17951: fix: macOS app: Skill binary detection does not respect /etc/paths ...
by MisterGuy420 · 2026-02-16
76.9%