Skip to content

Windows: spawnSync ENOENT — codex/npm not detected without shell:true #16

@gus2902

Description

@gus2902

Summary

On Windows, codex-companion.mjs setup reports codex, npm, and auth as "not found" even when all are correctly installed and available from the shell.

Root Cause

runCommand() in scripts/lib/process.mjs calls spawnSync(command, args, ...) with shell defaulting to false.

On Windows, npm global installs create .cmd batch wrappers (e.g., codex.cmd, npm.cmd). Node.js spawnSync with shell: false does not resolve .cmd extensions, so the call fails with ENOENT.

Environment

  • OS: Windows 11 Pro (10.0.26200)
  • Node.js: v23.10.0
  • npm: 11.12.1 (via Volta)
  • Codex CLI: 0.117.0 (installed at AppData/Roaming/npm/codex)
  • Claude Code: 2.1.87

Reproduction

// ENOENT — fails
spawnSync("codex", ["--version"], { encoding: "utf8" });

// Works — returns "codex-cli 0.117.0"
spawnSync("codex", ["--version"], { encoding: "utf8", shell: true });

Setup output before fix:

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

Suggested Fix

In scripts/lib/process.mjs, add shell: true on Windows:

 export function runCommand(command, args = [], options = {}) {
+  const useShell = options.shell ?? (process.platform === "win32");
   const result = spawnSync(command, args, {
     cwd: options.cwd,
     env: options.env,
     encoding: "utf8",
     input: options.input,
-    stdio: options.stdio ?? "pipe"
+    stdio: options.stdio ?? "pipe",
+    shell: useShell
   });

This is safe because:

  • Only activates on win32, no impact on macOS/Linux
  • options.shell allows callers to override if needed
  • Fixes detection for all npm-global-installed binaries (codex, npm, etc.)

After Fix

{
  "ready": true,
  "npm": { "available": true, "detail": "11.12.1" },
  "codex": { "available": true, "detail": "codex-cli 0.117.0; advanced runtime available" },
  "auth": { "available": true, "loggedIn": true, "detail": "authenticated" }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions