windmill-labs/windmill · error

npm exited with ${exitCode === null ? "a signal" : `code ${e

Error message

npm exited with ${exitCode === null ? "a signal" : `code ${exitCode}`}${detail ? `:
${detail}` : ""}

${HINT}

What it means

Thrown by the windmill CLI's `upgrade` function when the spawned npm process completes but exits with a non-zero code (or is killed by a signal). The npm stdout/stderr output is appended to the message so the real cause (permissions, network, registry errors) is visible.

Source

Thrown at cli/src/utils/upgrade.ts:111

      output.push(String(d));
      if (verbose) process.stderr.write(d);
    });
    // `error` fires when npm can't be spawned at all; without a listener that
    // is an uncaught exception, crashing before any hint prints. `close`
    // resolves null when npm died from a signal — a failure too.
    const exitCode: number | null = await new Promise<number | null>(
      (resolve, reject) => {
        proc.on("error", reject);
        proc.on("close", resolve);
      }
    ).catch((e) => {
      throw new Error(
        `failed to run npm: ${e instanceof Error ? e.message : e}\n\n${HINT}`
      );
    });
    if (exitCode !== 0) {
      const detail = output.join("").trim();
      throw new Error(
        `npm exited with ${
          exitCode === null ? "a signal" : `code ${exitCode}`
        }${detail ? `:\n${detail}` : ""}\n\n${HINT}`
      );
    }
  }
}

type NpmApiPackageMetadata = {
  "dist-tags": {
    latest: string;
  };
  versions: {
    [version: string]: unknown;
  };
};

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the `detail` section of the message for npm's actual error and fix it (e.g. EACCES → fix npm prefix or use a node version manager)
  2. Upgrade manually: `npm install -g windmill-cli@latest` (with sudo only if unavoidable)
  3. Check network/proxy access to the npm registry (`npm ping`), then retry `wmill upgrade`

Example fix

// before
wmill upgrade
// npm exited with code 1:
// EACCES: permission denied ...
// after (permission fix)
npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH"
wmill upgrade
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = spawnSync('npm', ['ping'], { stdio: 'ignore' });
if (probe.status !== 0) throw new Error('npm registry unreachable; fix network/proxy before upgrading');

Try / catch

try {
  await upgrade();
} catch (e) {
  if (e.message.startsWith('npm exited with')) {
    // npm output follows the colon; surface it to the user
    console.error(e.message);
    console.error('Run `npm install -g windmill-cli@latest` manually and retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `wmill upgrade` when `npm install -g windmill-cli@latest` fails: no write permission to the global node_modules, network/registry outage, or npm peer-dependency conflicts.

Common situations: Global installs requiring sudo (EACCES); corporate proxies blocking registry.npmjs.org; interrupted install leaving npm in a bad state; Windows file locks on the binary being replaced.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/98948bdd6f690963. Report an issue: GitHub.