pulumi/pulumi · error
find npm: %w
Error message
find npm: %w
What it means
Pack resolves npm once at the start of the language host's Pack method via executable.FindExecutable("npm") (sdk/nodejs/cmd/pulumi-language-nodejs/main.go:1983). If no npm binary can be located on PATH (or via nodeenv paths), the error is wrapped as "find npm: %w" and packing aborts before reading package.json.
Source
Thrown at sdk/nodejs/cmd/pulumi-language-nodejs/main.go:1983
func readPackageJSON(packageJSONPath string) (map[string]any, error) {
packageJSONData, err := os.ReadFile(packageJSONPath)
if err != nil {
return nil, fmt.Errorf("read package.json: %w", err)
}
var packageJSON map[string]any
err = json.Unmarshal(packageJSONData, &packageJSON)
if err != nil {
return nil, fmt.Errorf("unmarshal package.json: %w", err)
}
return packageJSON, nil
}
func (host *nodeLanguageHost) Pack(ctx context.Context, req *pulumirpc.PackRequest) (*pulumirpc.PackResponse, error) {
// Verify npm exists and is set up: npm, user login
npm, err := executable.FindExecutable("npm")
if err != nil {
return nil, fmt.Errorf("find npm: %w", err)
}
// Annoyingly the engine will call Pack for the core SDK which is not setup in at all the same way as the
// generated sdks, so we have to detect that and do a big branch to pack it totally differently.
packageJSON, err := readPackageJSON(filepath.Join(req.PackageDirectory, "package.json"))
if err != nil {
return nil, err
}
// TODO: We're just going to write to stderr for now, but we should probably have a way to return this
// directly to the engine hosting us. That's a bit awkward because we need the subprocesses to write to
// this as well, and the host side of this pipe might be a tty and if it is we want the subprocesses to
// think they're connected to a tty as well. We've solved this problem before in two slightly different
// ways for InstallDependencies and RunPlugin, it would be good to come up with a clean way to do this for
// all these cases.
writeString := func(s string) error {
_, err = os.Stderr.Write([]byte(s))
return errView on GitHub (pinned to 793f7b2e16)
Solutions
- Install Node.js (which bundles npm) in the environment running pulumi, e.g. via nvm, volta, mise, or the OS package manager
- Ensure the directory containing npm is on PATH for the shell/process invoking pulumi: 'which npm' must succeed
- In CI, use a setup-node/setup step before running pulumi commands
- If using nvm, confirm the default alias exists ('nvm alias default') so non-interactive shells resolve node/npm
- As a workaround, symlink npm into a directory already on PATH
Example fix
// before $ pulumi package pack-sdk nodejs ./provider error: find npm: exec: "npm": executable file not found in $PATH // after $ export PATH="$HOME/.nvm/versions/node/v20.11.0/bin:$PATH" $ which npm $ pulumi package pack-sdk nodejs ./provider
Defensive patterns
Strategy: validation
Validate before calling
if ! command -v npm >/dev/null 2>&1; then echo "npm not found on PATH"; exit 1 fi
Try / catch
try {
child_process.execSync('npm --version');
} catch (err) {
console.error('npm is not available on PATH; install Node.js first');
process.exit(1);
} Prevention
- Install Node.js via a version manager and ensure the shell init (nvm/volta/mise) runs in non-interactive shells too
- Verify 'which npm' before running pulumi pack commands in CI
- Add a setup-node step before any pulumi invocation
- Keep PATH consistent between your shell and the process invoking pulumi
When it happens
Trigger: Calling Pack (e.g. 'pulumi package pack-sdk' or 'pulumi plugin install' flows that build a Node package) on a machine where the 'npm' executable is not on PATH and not in the nodeenv/npm shims the host checks.
Common situations: Node.js not installed in the environment running the pulumi CLI; npm not installed despite node being present (e.g. custom node builds); PATH stripped of nvm/volta/n dirs in CI or non-interactive shells; mise/asdf shim directories missing.
Related errors
- could not find npm on the $PATH; npm is installed with Node.
- Could not find `npm` executable. Install npm and make sure i
- error while looking for fnm: %w
- could not find executable %q: %w
- the project's manifest is package.yaml, which requires pnpm,
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/9ee4b5cba348e586.
Report an issue: GitHub.