Skip to content

fix(dev-launcher): make npm run dev work on Windows#118

Open
Fronut wants to merge 1 commit into
OpenBMB:mainfrom
Fronut:fix/windows-dev-launcher-spawn
Open

fix(dev-launcher): make npm run dev work on Windows#118
Fronut wants to merge 1 commit into
OpenBMB:mainfrom
Fronut:fix/windows-dev-launcher-spawn

Conversation

@Fronut
Copy link
Copy Markdown

@Fronut Fronut commented Jun 2, 2026

Summary

npm run dev fails immediately on Windows because scripts/dev-launcher.mjs
spawns npm without a shell. This PR makes the launcher cross-platform so the
documented "From source (for developers)" quick-start works out of the box on
Windows, while leaving the macOS/Linux behavior unchanged.

Problem

On a fresh clone, following the README quick-start (npm install then
npm run dev) on Windows produces:

[dev-launcher] resolved dev ports:
  server (express/ws)  →  3001
  gateway (pilotdeck)  →  18789
  vite client          →  5173

Error: spawn npm ENOENT
    ...
  syscall: 'spawn npm',
  path: 'npm',
  spawnargs: [ '--workspace', 'ui', 'run', 'dev:concurrent' ]

Root cause:

  • On Windows the npm executable is a npm.cmd shim. child_process.spawn('npm', ...)
    without a shell cannot resolve it, so it throws ENOENT.
  • Simply switching to the npm.cmd name is not enough: recent Node.js releases
    refuse to spawn .cmd/.bat files without a shell and throw spawn EINVAL
    (a security hardening change related to CVE-2024-27980).

Fix

In scripts/dev-launcher.mjs, on win32 only:

  • use npm.cmd as the command, and
  • pass shell: true.

macOS/Linux keep the original plain, shell-free spawn('npm', ...).

The spawn arguments here are fixed string literals (--workspace, ui, run,
dev:concurrent) with no user input, so enabling the shell on Windows carries
no command-injection risk.

const isWindows = process.platform === 'win32';
const npmCommand = isWindows ? 'npm.cmd' : 'npm';
const child = spawn(
  npmCommand,
  ['--workspace', 'ui', 'run', 'dev:concurrent'],
  { cwd: repoRoot, env, stdio: 'inherit', shell: isWindows },
);

Testing

Verified on Windows (PowerShell, Node.js v22.14.0, npm 10.9.2):

  • npm run dev now boots all three processes successfully:
    • vite client → http://localhost:5173 (HTTP 200)
    • server (express/ws) → http://localhost:3001 (HTTP 200, "PilotDeck Server - Ready")
    • gateway (pilotdeck) → ws://127.0.0.1:18789/ws (listening)
  • No ENOENT / EINVAL in stderr.

macOS/Linux code path is unchanged (still plain spawn('npm', ...) with no shell).

Scope

This PR intentionally fixes only the developer quick-start entry point
(dev-launcher.mjs), which is the one blocker that prevents npm run dev from
starting at all on Windows. Other spawn('npm'|'npx', ...) call sites in
runtime/optional feature paths are out of scope here and can be addressed
separately if desired.

On Windows the npm executable is a npm.cmd shim. `npm run dev` (which runs
scripts/dev-launcher.mjs) crashed immediately with `spawn npm ENOENT`, and
switching to the `npm.cmd` name alone then failed with `spawn EINVAL` because
recent Node.js releases refuse to spawn .cmd/.bat files without a shell
(hardening from CVE-2024-27980).

Use `npm.cmd` plus `shell: true` on win32 and keep the plain, shell-free spawn
on macOS/Linux. The spawn arguments are fixed literals with no user input, so
enabling the shell carries no injection risk. This makes `npm run dev` work out
of the box on Windows.
@Fronut Fronut changed the title fix(dev-launcher): make pm run dev work on Windows fix(dev-launcher): make npm run dev work on Windows Jun 2, 2026
@Fronut Fronut marked this pull request as ready for review June 2, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant