[GH-ISSUE #2319] [Bug] Windows: test:focused fails with 'C:\Program' is not recognized #768

Closed
opened 2026-10-15 18:28:10 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @harshdazz on GitHub (Oct 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2319

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Other (development scripts)

Observed behavior

On Windows, npm run test:focused fails before any test runs whenever a selected file needs a build, which is any path outside src/, tests/composition/, tests/conformance/ and tests/evaluation/ (sourceTest in scripts/lib/development-tests.mjs):

'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

Node is in the installer's default location, C:\Program Files\nodejs. test:local and test:changed aren't affected because they only accept source tests, which don't go through the runner.

Reproduction

  1. Windows with Node installed under C:\Program Files\nodejs.
  2. npm run test:focused -- tests/process-global/runnerCancellation.test.ts
  3. Exit 1 with the error above, no tests run.

Smaller, straight through the runner:

node scripts/run-exclusive.mjs probe "C:\Program Files\nodejs\node.exe" -e "console.log('child ran')"

prints the same error. With a bare node the command starts, but the -e argument gets split at the space (SyntaxError: Invalid or unexpected token).

The existing test "does not treat an old database timestamp as permission to replace a live owner" in tests/process-global/runnerCancellation.test.ts also fails on Windows for this reason: its launch helper passes process.execPath, so the contender's stderr is the 'C:\Program' error instead of "already running".

Expected behavior

The runner starts the selected command with its path and arguments unchanged, so test:focused runs the tests.

Impact and scope

Development scripts only. scripts/run-exclusive-command.mjs isn't in the npm package, so the published CLI and MCP server aren't affected. It hits Windows contributors whose Node path has a space, which is the installer default. npm run check, build:cached and the other package scripts still work because they pass bare command names (turbo, node, npm). CI doesn't catch it: the Linux jobs don't use a shell here, and the Windows job runs npm run build:cached and npx vitest run directly, not test:focused, and doesn't include runnerCancellation.test.ts.

REA version

source a97b713f

Runtime and platform

Node 22.19.0; Windows 11 x64 (10.0.26300)

Target and artifact context

Not applicable

Interface

Other (development scripts)

Earliest failure stage

Starting the command in scripts/run-exclusive-command.mjs (not one of the listed stages)

Relevant output or evidence

$ npx vitest run --project process-global tests/process-global/runnerCancellation.test.ts
 × does not treat an old database timestamp as permission to replace a live owner 335ms
- Expected
+ Received
  {
    "code": 1,
-   "stderr": StringContaining "already running",
+   "stderr": "(node:7684) ExperimentalWarning: SQLite is an experimental feature and might change at any time
+ (Use `node --trace-warnings ...` to show where the warning was created)
+ 'C:\\Program' is not recognized as an internal or external command,
+ operable program or batch file.
+ ",
    "stdout": "",
  }
      Tests  1 failed | 3 skipped (4)

Analysis or suspected cause

Source-derived: runCommand() in scripts/run-exclusive-command.mjs spawns with shell: process.platform === "win32". With shell: true, Node joins the command and its arguments into one cmd.exe line without quoting them. Checked with child.spawnargs:

["C:\\WINDOWS\\system32\\cmd.exe","/d","/s","/c","\"C:\\Program Files\\nodejs\\node.exe -e console.log(1)\""]

scripts/run-development-tests.mjs passes process.execPath as the command, so cmd.exe splits it at the space. The shell is still needed for bare names like turbo and npm, which resolve to .cmd shims.

Additional context

I have a fix ready: spawn .exe / .com paths directly and keep the shell only for bare commands. I'll open the PR right after this. Found while working on #2302.

Originally created by @harshdazz on GitHub (Oct 12, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2319 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Other (development scripts) ### Observed behavior On Windows, `npm run test:focused` fails before any test runs whenever a selected file needs a build, which is any path outside `src/`, `tests/composition/`, `tests/conformance/` and `tests/evaluation/` (`sourceTest` in `scripts/lib/development-tests.mjs`): ```text 'C:\Program' is not recognized as an internal or external command, operable program or batch file. ``` Node is in the installer's default location, `C:\Program Files\nodejs`. `test:local` and `test:changed` aren't affected because they only accept source tests, which don't go through the runner. ### Reproduction 1. Windows with Node installed under `C:\Program Files\nodejs`. 2. `npm run test:focused -- tests/process-global/runnerCancellation.test.ts` 3. Exit 1 with the error above, no tests run. Smaller, straight through the runner: ```text node scripts/run-exclusive.mjs probe "C:\Program Files\nodejs\node.exe" -e "console.log('child ran')" ``` prints the same error. With a bare `node` the command starts, but the `-e` argument gets split at the space (`SyntaxError: Invalid or unexpected token`). The existing test "does not treat an old database timestamp as permission to replace a live owner" in `tests/process-global/runnerCancellation.test.ts` also fails on Windows for this reason: its `launch` helper passes `process.execPath`, so the contender's stderr is the `'C:\Program'` error instead of "already running". ### Expected behavior The runner starts the selected command with its path and arguments unchanged, so `test:focused` runs the tests. ### Impact and scope Development scripts only. `scripts/run-exclusive-command.mjs` isn't in the npm package, so the published CLI and MCP server aren't affected. It hits Windows contributors whose Node path has a space, which is the installer default. `npm run check`, `build:cached` and the other package scripts still work because they pass bare command names (`turbo`, `node`, `npm`). CI doesn't catch it: the Linux jobs don't use a shell here, and the Windows job runs `npm run build:cached` and `npx vitest run` directly, not `test:focused`, and doesn't include `runnerCancellation.test.ts`. ### REA version source `a97b713f` ### Runtime and platform Node 22.19.0; Windows 11 x64 (10.0.26300) ### Target and artifact context Not applicable ### Interface Other (development scripts) ### Earliest failure stage Starting the command in `scripts/run-exclusive-command.mjs` (not one of the listed stages) ### Relevant output or evidence ```text $ npx vitest run --project process-global tests/process-global/runnerCancellation.test.ts × does not treat an old database timestamp as permission to replace a live owner 335ms - Expected + Received { "code": 1, - "stderr": StringContaining "already running", + "stderr": "(node:7684) ExperimentalWarning: SQLite is an experimental feature and might change at any time + (Use `node --trace-warnings ...` to show where the warning was created) + 'C:\\Program' is not recognized as an internal or external command, + operable program or batch file. + ", "stdout": "", } Tests 1 failed | 3 skipped (4) ``` ### Analysis or suspected cause Source-derived: `runCommand()` in `scripts/run-exclusive-command.mjs` spawns with `shell: process.platform === "win32"`. With `shell: true`, Node joins the command and its arguments into one `cmd.exe` line without quoting them. Checked with `child.spawnargs`: ```text ["C:\\WINDOWS\\system32\\cmd.exe","/d","/s","/c","\"C:\\Program Files\\nodejs\\node.exe -e console.log(1)\""] ``` `scripts/run-development-tests.mjs` passes `process.execPath` as the command, so `cmd.exe` splits it at the space. The shell is still needed for bare names like `turbo` and `npm`, which resolve to `.cmd` shims. ### Additional context I have a fix ready: spawn `.exe` / `.com` paths directly and keep the shell only for bare commands. I'll open the PR right after this. Found while working on #2302.
bsakaguchi 2026-10-15 18:28:10 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#768
No description provided.