Skip to content

fix: resolve ENOENT for .cmd shims on Windows#13

Merged
dkundel-openai merged 1 commit intoopenai:mainfrom
omid-method:fix/windows-spawnSync-shell
Mar 31, 2026
Merged

fix: resolve ENOENT for .cmd shims on Windows#13
dkundel-openai merged 1 commit intoopenai:mainfrom
omid-method:fix/windows-spawnSync-shell

Conversation

@omid-method
Copy link
Copy Markdown

Summary

  • Adds shell: process.platform === "win32" to spawnSync in runCommand(), fixing binary detection (codex, npm, etc.) on Windows

Problem

On Windows, npm installs global CLI tools as .cmd shims (e.g., codex.cmd). Node.js spawnSync() without shell: true calls CreateProcess, which only resolves .exe files — it cannot find .cmd or .bat files, even when they are on PATH.

This causes binaryAvailable("codex", ...) to return { available: false, detail: "not found" } on Windows, even with a correctly installed and PATH-accessible Codex CLI. The same applies to npm detection.

Before (on Windows)

codex: { available: false, detail: "not found" }
npm:   { available: false, detail: "not found" }

After

codex: { available: true, detail: "codex-cli 0.117.0; advanced runtime available" }
npm:   { available: true, detail: "11.6.3" }

Root cause

spawnSync("codex", ["--version"]) → Windows CreateProcess → searches for codex.exe only → ENOENT.

Adding shell: true routes through cmd.exe, which resolves commands using PATHEXT (.CMD, .BAT, etc.), matching how the Windows shell resolves commands.

Why this is safe

  • The condition process.platform === "win32" evaluates to false on macOS/Linux — zero behavior change on non-Windows platforms
  • shell: true is the standard Node.js pattern for cross-platform command resolution (used by cross-spawn, execa, and npm itself)
  • terminateProcessTree already works on Windows because taskkill is a native .exe, not a .cmd shim — so it is unaffected by this change

Test plan

  • Verified on Windows 11 + Node.js v22.21.0 + Codex CLI 0.117.0
  • /codex:setup reports all components as available after the fix
  • Verify no regression on macOS/Linux (condition is false, no code path change)

On Windows, Node.js `spawnSync` without `shell: true` uses
`CreateProcess`, which only resolves `.exe` files. npm installs global
tools (like `codex`) as `.cmd` shims, so `spawnSync("codex", ...)`
returns ENOENT even when codex is correctly installed and on PATH.

Adding `shell: process.platform === "win32"` routes through `cmd.exe`
on Windows, which properly resolves `.cmd`, `.bat`, and PATHEXT entries.
No behavior change on macOS/Linux since the condition evaluates to false.
@omid-method omid-method requested a review from a team March 30, 2026 21:24
@dkundel-openai
Copy link
Copy Markdown
Collaborator

@codex review

@dkundel-openai dkundel-openai merged commit cf6f851 into openai:main Mar 31, 2026
0xZOne added a commit to 0xZOne/codex-plugin-cc that referenced this pull request Mar 31, 2026
…lity

On Windows, `codex` is installed as an npm `.cmd` shim. Node's
`child_process.spawn()` cannot resolve `.cmd` files without
`shell: true`, causing `ENOENT` when `SpawnedCodexAppServerClient`
tries to start `codex app-server`.

This is the same class of bug fixed in openai#13 for `spawnSync` in
`process.mjs`, but the async `spawn()` call in `app-server.mjs`
was missed.
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.

3 participants