openclaw - 💡(How to fix) Fix [bug] launchd-submitted self-update script fails with "env: node: No such file or directory" (npm exit 127) on macOS Homebrew installs [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#74944Fetched 2026-05-01 05:39:46
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
2
Author
Timeline (top)
commented ×1

On macOS where Node is installed via Homebrew, the launchctl submit-based self-update path (e.g. triggered from the Discord channel: "update to 2026.4.27") fails repeatedly with env: node: No such file or directory and npm exit: 127. The submitted job retries forever (I observed runs = 59 before manual intervention), keeps spawning the gateway in a crash loop, and the user is left unable to upgrade.

Root Cause

launchctl print gui/\$UID/openclaw-update-2026-4-27 showed: ``` default environment = { PATH => /usr/bin:/bin:/usr/sbin:/sbin } ``` The submitted job inherits launchd's minimal default PATH. The script calls /opt/homebrew/bin/npm by absolute path, but npm itself is a Node shim whose shebang resolves Node via env node — which fails because /opt/homebrew/bin (and /opt/homebrew/opt/node/bin) are not in PATH.

Resulting log loop (every ~17s, 59 retries observed): ``` Installing [email protected] via npm... env: node: No such file or directory npm exit: 127 ```

Meanwhile the watchdog kept kickstarting the gateway each iteration, producing a separate crash loop on port 18789.

Fix Action

Workaround

Manual upgrade in an interactive shell (where Homebrew PATH is present): ```bash launchctl remove openclaw-update-<ver> # stop the failed loop launchctl bootout gui/$UID/com.openclaw.watchdog # stop the kickstart fight launchctl bootout gui/$UID/ai.openclaw.gateway pkill -9 -f openclaw npm install -g openclaw@latest openclaw doctor --repair --non-interactive launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.openclaw.watchdog.plist launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.gateway.plist launchctl kickstart -k gui/$UID/ai.openclaw.gateway ```

RAW_BUFFERClick to expand / collapse

Summary

On macOS where Node is installed via Homebrew, the launchctl submit-based self-update path (e.g. triggered from the Discord channel: "update to 2026.4.27") fails repeatedly with env: node: No such file or directory and npm exit: 127. The submitted job retries forever (I observed runs = 59 before manual intervention), keeps spawning the gateway in a crash loop, and the user is left unable to upgrade.

Environment

  • OpenClaw: 2026.4.26 → trying to upgrade to 2026.4.27
  • macOS: 26.4.1 (arm64)
  • Node: v25.4.0 at /opt/homebrew/bin/node
  • npm: /opt/homebrew/bin/npm
  • Install: global npm (/opt/homebrew/lib/node_modules/openclaw)

Repro

  1. Have OpenClaw running under the standard LaunchAgent setup on a Homebrew Mac.
  2. Trigger an update via the Discord channel (or anything that goes through the launchctl submit-based updater path).
  3. Observe ~/.openclaw/workspace/tmp/update_openclaw_<ver>_launchd.log and launchctl print gui/\$UID/openclaw-update-<ver>.

Root cause

launchctl print gui/\$UID/openclaw-update-2026-4-27 showed: ``` default environment = { PATH => /usr/bin:/bin:/usr/sbin:/sbin } ``` The submitted job inherits launchd's minimal default PATH. The script calls /opt/homebrew/bin/npm by absolute path, but npm itself is a Node shim whose shebang resolves Node via env node — which fails because /opt/homebrew/bin (and /opt/homebrew/opt/node/bin) are not in PATH.

Resulting log loop (every ~17s, 59 retries observed): ``` Installing [email protected] via npm... env: node: No such file or directory npm exit: 127 ```

Meanwhile the watchdog kept kickstarting the gateway each iteration, producing a separate crash loop on port 18789.

Suggested fix

In the launchd update script template (update_openclaw_<ver>_launchd.sh), explicitly set PATH at the top, e.g.: ```sh export PATH="/opt/homebrew/bin:/opt/homebrew/opt/node/bin:/usr/local/bin:$PATH" ``` Or invoke node directly: /opt/homebrew/opt/node/bin/node /opt/homebrew/lib/node_modules/npm/bin/npm-cli.js install -g openclaw@<ver>.

Either avoids the env node resolution under launchd's minimal PATH. The gateway plist itself is fine — it already pins /opt/homebrew/opt/node/bin/node as ProgramArguments[0]. Only the updater script regressed.

Workaround

Manual upgrade in an interactive shell (where Homebrew PATH is present): ```bash launchctl remove openclaw-update-<ver> # stop the failed loop launchctl bootout gui/$UID/com.openclaw.watchdog # stop the kickstart fight launchctl bootout gui/$UID/ai.openclaw.gateway pkill -9 -f openclaw npm install -g openclaw@latest openclaw doctor --repair --non-interactive launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.openclaw.watchdog.plist launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.gateway.plist launchctl kickstart -k gui/$UID/ai.openclaw.gateway ```

extent analysis

TL;DR

Explicitly setting the PATH environment variable in the launchd update script template can resolve the issue by ensuring Node and npm are accessible.

Guidance

  • Verify the launchd update script template (update_openclaw_<ver>_launchd.sh) and add export PATH="/opt/homebrew/bin:/opt/homebrew/opt/node/bin:/usr/local/bin:$PATH" at the top to set the PATH explicitly.
  • Alternatively, invoke Node directly by modifying the script to use /opt/homebrew/opt/node/bin/node /opt/homebrew/lib/node_modules/npm/bin/npm-cli.js install -g openclaw@<ver>.
  • Before applying the fix, stop the failed update loop and kickstart fight using the provided workaround commands.
  • After applying the fix, verify the update by checking the ~/.openclaw/workspace/tmp/update_openclaw_<ver>_launchd.log and launchctl print gui/$UID/openclaw-update-<ver>.

Example

export PATH="/opt/homebrew/bin:/opt/homebrew/opt/node/bin:/usr/local/bin:$PATH"

This sets the PATH environment variable to include the necessary directories for Node and npm.

Notes

The provided workaround can be used as a temporary solution to manually upgrade OpenClaw. However, applying the suggested fix to the launchd update script template is recommended for a permanent solution.

Recommendation

Apply the workaround to stop the failed loop and then modify the launchd update script template to set the PATH explicitly, as this resolves the root cause of the issue.

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 [bug] launchd-submitted self-update script fails with "env: node: No such file or directory" (npm exit 127) on macOS Homebrew installs [1 comments, 2 participants]