Skip to content

fix(installer): load nvm before Node.js version check#49673

Open
Chenglin97 wants to merge 1 commit intoopenclaw:mainfrom
Chenglin97:fix/installer-nvm-detection
Open

fix(installer): load nvm before Node.js version check#49673
Chenglin97 wants to merge 1 commit intoopenclaw:mainfrom
Chenglin97:fix/installer-nvm-detection

Conversation

@Chenglin97
Copy link
Copy Markdown

Problem

On systems where nvm manages Node.js, the installer runs in a non-interactive shell (e.g. curl ... | bash) where nvm is not loaded. The system-installed Node (e.g. /usr/bin/node v8) appeared earlier on PATH, causing check_node() to fail on the stale binary and trigger install_node() — overwriting the user's nvm environment unnecessarily.

Fix

Add a try_load_nvm() helper that sources ${NVM_DIR:-$HOME/.nvm}/nvm.sh with --no-use before check_node runs, then activates the nvm default alias. If nvm is not installed, it is a no-op.

try_load_nvm() {
    local nvm_dir="${NVM_DIR:-$HOME/.nvm}"
    if [[ -s "${nvm_dir}/nvm.sh" ]]; then
        . "${nvm_dir}/nvm.sh" --no-use
        if command -v nvm >/dev/null 2>&1; then
            nvm use default --silent 2>/dev/null || nvm use node --silent 2>/dev/null || true
        fi
    fi
}

Testing

  • System with nvm + Node 24 via nvm, Node 18 at /usr/bin/node: before fix → installs Node again; after fix → detects v24 correctly and skips install
  • System without nvm: try_load_nvm is a no-op, no behavior change

Fixes #49556

On systems where nvm manages Node.js, the installer was detecting the
system-installed Node (e.g. /usr/bin/node v8) because /usr/bin appears
before ~/.nvm/versions/node/.../bin on PATH in non-interactive shells.

This caused check_node() to fail on the stale system binary and trigger
install_node(), which overwrote the user's nvm environment unnecessarily.

Fix: add try_load_nvm() that sources ~/.nvm/nvm.sh (with --no-use to
avoid side effects) and activates the nvm default alias before check_node
runs. If nvm is not installed, try_load_nvm() is a no-op.

Fixes openclaw#49556
@openclaw-barnacle openclaw-barnacle bot added scripts Repository scripts size: XS labels Mar 18, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 18, 2026

Greptile Summary

This PR adds a try_load_nvm() helper to scripts/install.sh that proactively sources nvm.sh --no-use and activates the nvm default Node alias before check_node() runs. This correctly fixes the scenario where a stale system-installed Node (e.g. /usr/bin/node v8) appears earlier on PATH in a non-interactive shell (curl ... | bash), causing the installer to unnecessarily trigger install_node() and overwrite the user's nvm environment.

Key changes:

  • New try_load_nvm() function (lines 1398–1411): sources nvm if available, then calls nvm use default (falling back to nvm use node) with full error suppression — safe for systems without nvm.
  • Called in main() immediately before the check_node / install_node block (line 2362).

Minor concern:

  • The inline comment at line 1401 claims the function is "a no-op if nvm is not installed or already loaded," but when nvm is already present in the shell it still re-sources nvm.sh and calls nvm use default. The re-source is idempotent so it won't cause bugs, but the comment should be corrected to avoid confusing future maintainers.

Confidence Score: 4/5

  • This PR is safe to merge — the fix is well-scoped, correctly handles the edge cases, and degrades gracefully on systems without nvm.
  • The implementation correctly addresses the stated problem. Error handling (2>/dev/null || true) prevents failures on nvm-less systems, the --no-use flag prevents unintended side effects during nvm.sh sourcing, and placement before check_node() is correct. The only deduction is for the mildly inaccurate "no-op if already loaded" comment, which could mislead future contributors but does not affect runtime behaviour.
  • No files require special attention.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: scripts/install.sh
Line: 1401

Comment:
**Inaccurate "already loaded" no-op comment**

The comment states the function is "a no-op if nvm is not installed or **already loaded**," but this isn't true. When nvm is already available in the shell (`command -v nvm` succeeds before this function runs), the guard `[[ -s "${nvm_dir}/nvm.sh" ]]` is still true, so the function will:
1. Re-source `nvm.sh` with `--no-use` (generally idempotent, so harmless)
2. Call `nvm use default --silent`, potentially switching the active Node version

The behavior itself is intentional and fine — you *do* want to ensure the default nvm Node is active — but the comment is misleading. Either update the comment to reflect what actually happens, or add an early-return guard to make the "already loaded" case a true no-op:

```suggestion
    # Source nvm before checking Node.js so the installer uses the nvm-managed
    # version rather than a system-installed Node that may be too old.
    # This is a no-op if nvm is not installed. If nvm is already loaded,
    # it ensures the default alias is active.
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: "fix(installer): load..."

try_load_nvm() {
# Source nvm before checking Node.js so the installer uses the nvm-managed
# version rather than a system-installed Node that may be too old.
# This is a no-op if nvm is not installed or already loaded.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Inaccurate "already loaded" no-op comment

The comment states the function is "a no-op if nvm is not installed or already loaded," but this isn't true. When nvm is already available in the shell (command -v nvm succeeds before this function runs), the guard [[ -s "${nvm_dir}/nvm.sh" ]] is still true, so the function will:

  1. Re-source nvm.sh with --no-use (generally idempotent, so harmless)
  2. Call nvm use default --silent, potentially switching the active Node version

The behavior itself is intentional and fine — you do want to ensure the default nvm Node is active — but the comment is misleading. Either update the comment to reflect what actually happens, or add an early-return guard to make the "already loaded" case a true no-op:

Suggested change
# This is a no-op if nvm is not installed or already loaded.
# Source nvm before checking Node.js so the installer uses the nvm-managed
# version rather than a system-installed Node that may be too old.
# This is a no-op if nvm is not installed. If nvm is already loaded,
# it ensures the default alias is active.
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/install.sh
Line: 1401

Comment:
**Inaccurate "already loaded" no-op comment**

The comment states the function is "a no-op if nvm is not installed or **already loaded**," but this isn't true. When nvm is already available in the shell (`command -v nvm` succeeds before this function runs), the guard `[[ -s "${nvm_dir}/nvm.sh" ]]` is still true, so the function will:
1. Re-source `nvm.sh` with `--no-use` (generally idempotent, so harmless)
2. Call `nvm use default --silent`, potentially switching the active Node version

The behavior itself is intentional and fine — you *do* want to ensure the default nvm Node is active — but the comment is misleading. Either update the comment to reflect what actually happens, or add an early-return guard to make the "already loaded" case a true no-op:

```suggestion
    # Source nvm before checking Node.js so the installer uses the nvm-managed
    # version rather than a system-installed Node that may be too old.
    # This is a no-op if nvm is not installed. If nvm is already loaded,
    # it ensures the default alias is active.
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f2c58ff091

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1405 to +1408
. "${nvm_dir}/nvm.sh" --no-use
# Activate the default/current nvm Node version if one is set
if command -v nvm >/dev/null 2>&1; then
nvm use default --silent 2>/dev/null || nvm use node --silent 2>/dev/null || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid activating nvm's default Node before Linux installs

If a Linux user has nvm installed but their default/node alias still points to Node 20 or older, this now prepends that stale nvm binary to PATH before check_node() runs. install_node() then installs a compliant system Node.js, but the Linux branch never rewrites PATH, so ensure_default_node_active_shell() still sees the old nvm binary and aborts the installer. Before this change, the same machine would succeed by picking up the newly installed system Node instead of the old nvm default.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scripts Repository scripts size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Installer script does not respect nvm Node version (detects system Node instead)

1 participant