Skip to content

Global bins installed with npm install -g are not on PATH after the Node.js runtime is installed #66

Open

Description

@cloud-walker

Problem

After pnpm/setup@v3 installs Node.js, npm install -g <pkg> succeeds but the package's bin isn't on PATH. The next step gets command not found.

This breaks third-party actions that install their CLI with npm install -g and then call it by name. With actions/setup-node (or the runner's preinstalled Node.js) that pattern works, because npm's global bin directory is the same directory that holds node, which is on PATH.

We hit it with fallow-rs/fallow's action, which runs npm install -g fallow and then fallow ...:

Installed fallow fallow 3.19.0
verified: yes (sentinel /home/runner/setup-pnpm/global/v11/80c-18d9765f3a3f77ab-0/node_modules/.pnpm/node@runtime+24.20.0/node_modules/node/lib/node_modules/fallow/...)
...
analyze.sh: line 665: fallow: command not found

Why it happens

  • pnpm runtime set node <version> -g links only node into $PNPM_HOME/bin. The runtime package ships no npm.
  • So npm on an ubuntu-24.04 runner is the preinstalled one. Its shebang (#!/usr/bin/env node) now picks up the pnpm-installed node.
  • npm derives its default global prefix from process.execPath, which is the runtime's directory inside pnpm's global dir/store, not $PNPM_HOME/bin. npm install -g writes the package and its bin there, into a directory that isn't on PATH. It also writes into a directory pnpm manages, which probably isn't desirable either.

Reproduction (no runner needed)

With pnpm 12.6.0 on macOS arm64. The runner behaves the same way, as the log above shows.

export PNPM_HOME="$PWD/home" PATH="$PWD/home/bin:/usr/bin:/bin"
pnpm runtime set node 24.20.0 -g
ls home/bin            # node (no npm/npx)

# stand-in for the runner's preinstalled npm
curl -sL "$(curl -s https://registry.npmjs.org/npm/latest | jq -r .dist.tarball)" | tar xz
node package/bin/npm-cli.js prefix -g
# .../home/store/v11/links/@/node/24.20.0/<hash>/node_modules/node
node package/bin/npm-cli.js install -g cowsay
command -v cowsay      # (nothing)
ls "$(node package/bin/npm-cli.js prefix -g)/bin"   # cowsay cowthink node

Workaround

- uses: pnpm/setup@v3
- run: echo "$(npm prefix -g)/bin" >> "$GITHUB_PATH"

Possible fixes

  • Add npm's global bin directory to PATH after installing the Node.js runtime, like setup-node does in effect.
  • Or export NPM_CONFIG_PREFIX pointing to a directory the action puts on PATH, e.g. under dest. This would also keep npm install -g out of pnpm's own directories.
  • At least, document that npm install -g bins aren't on PATH.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions