openclaw - ✅(Solved) Fix [Bug]: installer silently proceeds past failed `brew install node@22` on macOS and emits misleading "was installed" error [1 pull requests, 1 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#70411Fetched 2026-04-23 07:25:06
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1

On macOS, when brew install node@22 fails during install.sh, the installer proceeds as if it succeeded and prints a misleading error plus PATH remediation pointing to /opt/homebrew/opt/node@22/bin — a directory that does not exist after the failed install.

Error Message

On macOS, when brew install node@22 fails during install.sh, the installer proceeds as if it succeeded and prints a misleading error plus PATH remediation pointing to /opt/homebrew/opt/node@22/bin — a directory that does not exist after the failed install. When brew install node@22 fails, the installer should stop, surface the brew error (or its captured log), and not print PATH advice that points at a nonexistent directory. The Node.js v22 was installed but this shell is using … remediation should apply only when node@22 is actually on disk but not first on PATH. ERROR Node.js v22 was installed but this shell is using v16.19.0 (/Users/<user>/.volta/bin/node) ERROR Node.js v22 was installed but this shell is using v16.19.0 (/Users/<user>/.volta/bin/node)

Root Cause

  • scripts/install.sh:1524-1532 (`install_node`) — `run_quiet_step "Installing node@22" brew install node@22` is called as a bare statement; its return is not checked before `brew link` and `ensure_macos_node22_active` run. `set -e` does not catch a non-zero return here because `run_quiet_step`'s verbose branch ends in `return $?`, which bash treats as self-handled.
  • scripts/install.sh:1308-1342 (`ensure_macos_node22_active`) — uses `brew --prefix node@22`, which returns `/opt/homebrew/opt/node@22` with exit 0 even for uninstalled formulae, to build the PATH remediation string. Emits `Node.js v22 was installed but this shell is using …` regardless of whether `${brew_node_prefix}/bin/node` exists.

Fix Action

Fix / Workaround

Additional information

  • Related: PR #51436 addresses the separate inappropriate ioctl for device leak in run_with_spinner. This issue is about the downstream silent-failure + misleading-remediation path and is independent.
  • Workaround: run brew install node@22 directly before invoking install.sh.

PR fix notes

PR #70432: fix(install): detect silent brew install failures on macOS

Description (problem / solution / changelog)

Summary

  • guard run_quiet_step's return in install_node so a failed brew install node@${NODE_DEFAULT_MAJOR} stops the installer instead of proceeding
  • split ensure_macos_default_node_active's error path into "bin missing on disk" vs "bin present but not first on PATH", so the was installed but this shell is using ... message is reserved for the PATH-ordering case it correctly describes

Context

On macOS, when brew install node@22 fails under the installer's gum spin wrapper, the installer still claims "Node.js v22 was installed" and prints PATH advice pointing to a directory that does not exist on disk.

Root cause:

  1. install_node called run_quiet_step as a bare statement, relying on set -e to abort. bash's errexit is suppressed for function calls whose last statement is return $? (as run_quiet_step's verbose branch does), so the non-zero return was silently ignored.
  2. ensure_macos_default_node_active emitted the same remediation message whether node@22's binary was actually on disk or not — and brew --prefix node@22 returns the canonical path with exit 0 even for uninstalled formulae, so the downstream -x "${prefix}/bin/node" guard only gated the PATH prepend, not the user-facing message.

Full repro and on-disk evidence in #70411.

Test plan

  • happy path: brew uninstall node@${NODE_DEFAULT_MAJOR}; rm -rf /opt/homebrew/opt/node@${NODE_DEFAULT_MAJOR}, then run the installer — should install node@${NODE_DEFAULT_MAJOR} and succeed as before
  • silent-failure repro (e.g. PATH=/usr/bin:/bin /path/to/install.sh where brew is unreachable) — installer should stop at the new brew install ... failed message instead of proceeding
  • PATH-ordering case: node@${NODE_DEFAULT_MAJOR} already installed but another node manager earlier on PATH — existing was installed but this shell is using ... message should still appear

Fixes #70411

Changed files

  • scripts/install.sh (modified, +13/-7)

Code Example

INFO Installing Node.js via Homebrew
inappropriate ioctl for device
ERROR Node.js v22 was installed but this shell is using v16.19.0 (/Users/<user>/.volta/bin/node)
Add this to your shell profile and restart shell:
  export PATH="/opt/homebrew/opt/node@22/bin:$PATH"

---

~ VERBOSE=1 /Users/<user>/Downloads/install.sh
✓ gum bootstrapped (temp, verified, v0.17.0)
Detected: macos

Install plan
OS                  macos
Install method      npm
Requested version   latest
INFO Existing OpenClaw installation detected, upgrading

[1/3] Preparing environment
Homebrew already installed
INFO Node.js v16.19.0 found, upgrading to v22+
INFO Installing Node.js via Homebrew
inappropriate ioctl for device
ERROR Node.js v22 was installed but this shell is using v16.19.0 (/Users/<user>/.volta/bin/node)
Add this to your shell profile and restart shell:
  export PATH="/opt/homebrew/opt/node@22/bin:$PATH"

---

$ ls /opt/homebrew/opt/node@22
ls: /opt/homebrew/opt/node@22: No such file or directory
$ brew list --versions | grep '^node'
(no output)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

On macOS, when brew install node@22 fails during install.sh, the installer proceeds as if it succeeded and prints a misleading error plus PATH remediation pointing to /opt/homebrew/opt/node@22/bin — a directory that does not exist after the failed install.

Steps to reproduce

  1. macOS with a prior Node manager (Volta / nvm / fnm) already on PATH resolving to node < 22.
  2. Run curl -fsSL https://openclaw.ai/install.sh | bash (or download and run) in a terminal where brew install node@22 fails under the installer's gum spin wrapper.
  3. Observe the output and the resulting on-disk state.

Expected behavior

When brew install node@22 fails, the installer should stop, surface the brew error (or its captured log), and not print PATH advice that points at a nonexistent directory. The Node.js v22 was installed but this shell is using … remediation should apply only when node@22 is actually on disk but not first on PATH.

Actual behavior

The installer emits:

INFO Installing Node.js via Homebrew
inappropriate ioctl for device
ERROR Node.js v22 was installed but this shell is using v16.19.0 (/Users/<user>/.volta/bin/node)
Add this to your shell profile and restart shell:
  export PATH="/opt/homebrew/opt/node@22/bin:$PATH"

…but /opt/homebrew/opt/node@22 does not exist on disk after the run, and brew list --versions | grep '^node' returns no rows. The PATH advice directs the user to prepend a nonexistent directory, leaving node still resolving via the previous manager.

OpenClaw version

installer script served by https://openclaw.ai/install.sh on 2026-04-22 (~87 KB)

Operating system

macOS 15 (Apple Silicon)

Install method

/Users/<user>/Downloads/install.sh (downloaded from openclaw.ai), invoked directly in an interactive zsh.

Model

NOT_ENOUGH_INFO

Provider / routing chain

NOT_ENOUGH_INFO

Logs, screenshots, and evidence

Transcript (second run, same outcome as the first):

➜  ~ VERBOSE=1 /Users/<user>/Downloads/install.sh
✓ gum bootstrapped (temp, verified, v0.17.0)
✓ Detected: macos

Install plan
OS                  macos
Install method      npm
Requested version   latest
INFO Existing OpenClaw installation detected, upgrading

[1/3] Preparing environment
✓ Homebrew already installed
INFO Node.js v16.19.0 found, upgrading to v22+
INFO Installing Node.js via Homebrew
inappropriate ioctl for device
ERROR Node.js v22 was installed but this shell is using v16.19.0 (/Users/<user>/.volta/bin/node)
Add this to your shell profile and restart shell:
  export PATH="/opt/homebrew/opt/node@22/bin:$PATH"

Post-run state:

$ ls /opt/homebrew/opt/node@22
ls: /opt/homebrew/opt/node@22: No such file or directory
$ brew list --versions | grep '^node'
(no output)

Running brew install node@22 directly in the same shell (no installer wrapping) succeeds and produces /opt/homebrew/opt/node@22/bin/node v22.22.2_2, confirming the failure is in how the installer wraps the invocation, not in brew itself.

Relevant code paths in the installer copy served by openclaw.ai:

  • scripts/install.sh:1524-1532 (`install_node`) — `run_quiet_step "Installing node@22" brew install node@22` is called as a bare statement; its return is not checked before `brew link` and `ensure_macos_node22_active` run. `set -e` does not catch a non-zero return here because `run_quiet_step`'s verbose branch ends in `return $?`, which bash treats as self-handled.
  • scripts/install.sh:1308-1342 (`ensure_macos_node22_active`) — uses `brew --prefix node@22`, which returns `/opt/homebrew/opt/node@22` with exit 0 even for uninstalled formulae, to build the PATH remediation string. Emits `Node.js v22 was installed but this shell is using …` regardless of whether `${brew_node_prefix}/bin/node` exists.

Impact and severity

  • Affected: macOS users with another Node manager (Volta / nvm / fnm) ahead of Homebrew on PATH, where brew install node@22 fails under the installer's wrapper.
  • Severity: medium. Real failure is hidden, the "was installed" message erodes trust, and the PATH advice points at a nonexistent directory.
  • Frequency: 2/2 runs on the reporting machine.
  • Consequence: installer one-liner cannot complete; user has to diagnose the silent brew failure manually.

Additional information

  • Related: PR #51436 addresses the separate inappropriate ioctl for device leak in run_with_spinner. This issue is about the downstream silent-failure + misleading-remediation path and is independent.
  • Workaround: run brew install node@22 directly before invoking install.sh.

extent analysis

TL;DR

The installer should check the return value of brew install node@22 and handle the case where it fails, instead of proceeding as if the installation was successful.

Guidance

  • Check the return value of brew install node@22 in the install_node function and handle the failure case.
  • Modify the ensure_macos_node22_active function to check if the Node.js binary exists at the expected path before emitting the PATH remediation string.
  • Consider adding error handling for the inappropriate ioctl for device error to prevent it from being hidden.
  • Verify that the installer correctly handles the case where brew install node@22 fails by running the installer with a simulated failure.

Example

# In scripts/install.sh:1524-1532
install_node() {
  if! run_quiet_step "Installing node@22" brew install node@22; then
    echo "Error: Failed to install node@22"
    # Handle failure case, e.g., exit the installer
  fi
  #...
}

Notes

The issue is specific to the installer script and how it handles the failure of brew install node@22. The workaround of running brew install node@22 directly before invoking install.sh suggests that the issue is not with Homebrew itself, but with the installer's handling of the installation process.

Recommendation

Apply a workaround by running brew install node@22 directly before invoking install.sh, until the installer is updated to handle the failure case correctly. This ensures that the Node.js installation is successful and the installer can proceed correctly.

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

When brew install node@22 fails, the installer should stop, surface the brew error (or its captured log), and not print PATH advice that points at a nonexistent directory. The Node.js v22 was installed but this shell is using … remediation should apply only when node@22 is actually on disk but not first on PATH.

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]: installer silently proceeds past failed `brew install node@22` on macOS and emits misleading "was installed" error [1 pull requests, 1 participants]