{"record":{"id":"0f5d492f1461091c","repo":"windmill-labs/windmill","slug":"failed-to-run-npm-e-instanceof-error-e-messag","errorCode":null,"errorMessage":"failed to run npm: ${e instanceof Error ? e.message : e}\n\n${HINT}","messagePattern":"failed to run npm: (.+?)\n\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/utils/upgrade.ts","lineNumber":105,"sourceCode":"    const output: string[] = [];\n    proc.stdout?.on(\"data\", (d) => {\n      output.push(String(d));\n      if (verbose) process.stdout.write(d);\n    });\n    proc.stderr?.on(\"data\", (d) => {\n      output.push(String(d));\n      if (verbose) process.stderr.write(d);\n    });\n    // `error` fires when npm can't be spawned at all; without a listener that\n    // is an uncaught exception, crashing before any hint prints. `close`\n    // resolves null when npm died from a signal — a failure too.\n    const exitCode: number | null = await new Promise<number | null>(\n      (resolve, reject) => {\n        proc.on(\"error\", reject);\n        proc.on(\"close\", resolve);\n      }\n    ).catch((e) => {\n      throw new Error(\n        `failed to run npm: ${e instanceof Error ? e.message : e}\\n\\n${HINT}`\n      );\n    });\n    if (exitCode !== 0) {\n      const detail = output.join(\"\").trim();\n      throw new Error(\n        `npm exited with ${\n          exitCode === null ? \"a signal\" : `code ${exitCode}`\n        }${detail ? `:\\n${detail}` : \"\"}\\n\\n${HINT}`\n      );\n    }\n  }\n}\n\ntype NpmApiPackageMetadata = {\n  \"dist-tags\": {\n    latest: string;\n  };","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/utils/upgrade.ts#L87-L123","documentation":"Thrown by the windmill CLI's `upgrade` function when the spawned npm process (used to install/update the CLI globally) emits an 'error' event instead of exiting — i.e. it could not be launched at all. The message embeds the underlying Node error and a HINT explaining how to upgrade manually.","triggerScenarios":"Calling `wmill upgrade` when npm is not installed or not on PATH, the npm binary lacks execute permission, or spawn fails for OS/arch reasons (e.g. nvm-managed node removed from PATH).","commonSituations":"Node installed via nvm/fnm and the current shell lacks the node path; Windows environments where 'npm' needs shell resolution; minimal Docker images without npm.","solutions":["Install Node.js/npm and ensure `npm --version` works in the same shell","Reinstall the CLI manually with `npm install -g windmill-cli@latest` (see HINT in the message)","If using nvm, run `nvm use <version>` or add node to PATH before running `wmill upgrade`"],"exampleFix":"// before (npm missing)\nwmill upgrade\n// Error: failed to run npm: spawn npm ENOENT\n// after\nexport PATH=\"$HOME/.nvm/versions/node/v20.11.0/bin:$PATH\"\nwmill upgrade","handlingStrategy":"try-catch","validationCode":"const hasNpm = spawnSync('npm', ['--version'], { stdio: 'ignore' }).status === 0;\nif (!hasNpm) throw new Error('npm is not available on PATH; install Node.js first');","typeGuard":null,"tryCatchPattern":"try {\n  await upgrade();\n} catch (e) {\n  if (String(e.message).startsWith('failed to run npm:')) {\n    console.error('npm could not be launched:', e.message);\n    // fallback: manual install instructions\n  } else throw e;\n}","preventionTips":["Verify `npm --version` works in the shell before running `wmill upgrade`","Keep node/npm on PATH in CI and scripts (especially with nvm/fnm)","Prefer installing via npm directly if the environment cannot spawn child processes"],"tags":["cli","npm","spawn","upgrade","path"],"backgroundTag":"spawn-enoent","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}