Skip to content

fix(install): make npm install -g packages reachable on PATH - #46085

Merged
ethernet8023 merged 3 commits into
NousResearch:mainfrom
xxxigm:fix/bundled-node-global-npm-path
Jun 15, 2026
Merged

ethernet8023 merged 3 commits into
NousResearch:mainfrom
xxxigm:fix/bundled-node-global-npm-path

Conversation

@xxxigm

@xxxigm xxxigm commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes "I can npm i -g <pkg> but the package isn't usable on the command line" after a quick install — reported by a user whose globally-installed npm binaries were not on PATH.

Root cause

When the installer can't find a suitable system Node, it installs a bundled Node into $HERMES_HOME/node/ and symlinks only node, npm, npx into the command link dir (~/.local/bin, /usr/local/bin, or $PREFIX/bin), which it ensures is on PATH.

But the bundled Node's npm uses its default global prefix, which is the Node install dir:

$ npm prefix -g
/home/user/.hermes/node

So npm install -g <pkg> drops the package binary in $HERMES_HOME/node/bin/<pkg> — a directory that is not on PATH (only the link dir is). The user's global binaries are therefore unreachable even though npm i -g succeeds. Worse, $HERMES_HOME/node is rm -rf'd and re-extracted on every Node upgrade, so those globals are also wiped.

Reproduced on a real Hermes-managed install:

$ command -v node            # ~/.local/bin/node (symlink, on PATH)
$ npm prefix -g              # ~/.hermes/node   ← globals land in ~/.hermes/node/bin (OFF PATH)

The fix

Redirect the bundled Node's npm global prefix to the command link dir's parent, so global bins land in the link dir itself — already on PATH, alongside node/npm/npx, and surviving Node upgrades:

printf 'prefix=%s\n' "$(dirname "$node_link_dir")" > "$HERMES_HOME/node/etc/npmrc"
  • ~/.local/bin user install → prefix ~/.local → bins in ~/.local/bin
  • root FHS install → prefix /usr/local → bins in /usr/local/bin
  • Termux → prefix $PREFIX → bins in $PREFIX/bin

It's written to the bundled Node's prefix-local global npmrc ($HERMES_HOME/node/etc/npmrc, npm's default globalconfig for that Node), so it is scoped to the Hermes-managed Node only — the user's other Node installs and their ~/.npmrc are untouched. Hermes's own global install (agent-browser) passes an explicit --prefix "$HERMES_HOME/node" (CLI overrides config) and is unaffected.

Verified end-to-end against a real bundled Node: with the redirect, npm prefix -g returns ~/.local and ~/.local/bin is confirmed on PATH.

The same fix is applied to both bundled-install paths: scripts/install.sh (install_node) and scripts/lib/node-bootstrap.sh (_nb_install_bundled_node).

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • scripts/install.sh: after symlinking node/npm/npx, write prefix=<link-dir parent> to $HERMES_HOME/node/etc/npmrc.
  • scripts/lib/node-bootstrap.sh: same redirect in the bundled-Node fallback.
  • tests/test_install_sh_node_global_prefix.py: assert both scripts perform the redirect.

How to Test

scripts/run_tests.sh tests/test_install_sh_node_global_prefix.py
# Manual: on a bundled-Node install, `npm i -g cowsay && cowsay hi` now works.

xxxigm added 3 commits June 14, 2026 17:21
When the installer falls back to a bundled Node under $HERMES_HOME/node,
npm's default global prefix is that Node dir, so `npm install -g <pkg>`
drops the package binary in $HERMES_HOME/node/bin. Only node/npm/npx are
symlinked into the command link dir (~/.local/bin, /usr/local/bin, or
$PREFIX/bin) — so user-installed global package binaries are NOT on PATH
and can't be run, even though `npm i -g` reports success. They also get
wiped on every Node upgrade (the dir is rm -rf'd and re-extracted).

Redirect the bundled Node's npm global prefix to the command link dir's
parent, so global bins land in the link dir (already on PATH, alongside
node/npm/npx) and survive Node upgrades. Scoped to the bundled Node via
its prefix-local global npmrc ($HERMES_HOME/node/etc/npmrc), so the user's
other Node installs and their ~/.npmrc are untouched. Hermes's own global
installs (agent-browser) pass an explicit --prefix and are unaffected.
Guards that install.sh and node-bootstrap.sh redirect the bundled Node's
npm global prefix to the command link dir's parent via a prefix-local
global npmrc, so `npm install -g` binaries land on PATH instead of the
off-PATH $HERMES_HOME/node/bin.
The initial fix only wrote the prefix npmrc on a fresh Node install, so
pre-existing bundled-Node installs (Node already present) were not repaired
by re-running the installer — install_node/ensure_node skip when Node is
already up to date.

Extract the redirect into an idempotent helper
(configure_managed_node_npm_prefix / _nb_configure_npm_prefix) that no-ops
when there's no Hermes-managed npm, and call it unconditionally from
check_node (install.sh) and at the top of ensure_node (node-bootstrap.sh).
Re-running the install command now repairs an affected install in place,
not just brand-new ones.
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard area/config Config system, migrations, profiles P2 Medium — degraded but workaround exists labels Jun 14, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Reviewed and verified end-to-end — this is a clean fix for a real bug.

Premise confirmed. On the bundled-Node fallback, npm's default global prefix is the Node dir, so npm install -g <pkg> drops binaries in $HERMES_HOME/node/bin — off PATH (only the command link dir is) and wiped on every Node upgrade. Reproduced the reported "I can npm i -g but the command isn't found" symptom.

Mechanism is correct and well-scoped. Writing prefix= to $HERMES_HOME/node/etc/npmrc lands in npm's per-Node global config, so the override applies only to the Hermes-managed Node — the user's nvm/system Node and their ~/.npmrc are untouched. Confirmed npm honors prefix= from the global npmrc. The redirect targets the link dir's parent (~/.local), so global bins resolve to ~/.local/bin alongside the node/npm/npx symlinks already on PATH, and survive Node upgrades since they live outside node/bin. Matches the manual workaround given to the reporter exactly.

Idempotent / repairs existing installs. The no-op guard ([ -x "$HERMES_HOME/node/bin/npm" ] || return 0) plus calling it from check_node / ensure_node means re-running the installer fixes pre-existing managed installs, not just fresh ones.

Validation:

  • npm prefix=-from-global-npmrc behavior verified locally.
  • The 3 regression tests pass.
  • CI fully green (6 test shards + amd64/arm64 builds + nix + e2e + attribution).

No issues found. Plan: salvage onto current main (58 commits behind, install-scripts only — no conflict), rebase-merge to preserve @xxxigm's authorship.

cc @expede @ethernet8023

@ethernet8023
ethernet8023 merged commit 39f479c into NousResearch:main Jun 15, 2026
28 checks passed
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 18, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
Methodician added a commit to Methodician/hermes-agent that referenced this pull request Jul 4, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…obal-npm-path

fix(install): make `npm install -g` packages reachable on PATH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants