Ctrl+G $EDITOR on Windows: spawn EINVAL on .cmd shims (CVE-2024-27980)

Resolved 💬 1 comment Opened May 8, 2026 by weichensw Closed Jun 5, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (closest matches in Additional Information)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code (2.1.132)

What's Wrong?

On Windows, pressing Ctrl+G in Claude Code's chat input fails immediately with:

<editor>.cmd quit unexpectedly (exit code 1)

The editor never launches; the .cmd body is never executed (verifiable: prepend dir > C:\tmp\trace.txt to the shim — no file appears). Reproduces with any $EDITOR whose path ends in .cmd, including every npm-installed wrapper shim. Linux is unaffected because $EDITOR there is typically a shell script with a shebang, which uses a different code path.

What Should Happen?

Pressing Ctrl+G should launch the configured external editor and load the chat-input contents into a temp file for editing — same as on Linux/macOS.

Error Messages/Logs

<editor>.cmd quit unexpectedly (exit code 1)

Steps to Reproduce

  1. On Windows with Node ≥ 18.20.0 (or 20.12.0 / 21.7.0), set $EDITOR to any .cmd file (an npm-installed wrapper, or a hand-written .cmd that calls a real editor).
  2. Launch Claude Code.
  3. Press Ctrl+G in the chat input.

Result: the status line shows <editor>.cmd quit unexpectedly (exit code 1) instantly. The shim's first line never runs.

Standalone reproducer (no Claude Code involvement)
// spawn-test.mjs
import { spawn } from 'node:child_process';
try {
  spawn('C:\\Users\\me\\AppData\\Roaming\\npm\\my-editor.cmd',
        ['C:\\tmp\\foo.txt'], { stdio: 'inherit' });
} catch (e) {
  console.log('sync throw:', e.code, e.message);
}
> node spawn-test.mjs
sync throw: EINVAL spawn EINVAL

The same .cmd invoked through cmd.exe directly runs fine, proving the shim is healthy. Only child_process.spawn without shell: true refuses it.

Root cause

Since Node 18.20.0 / 20.12.0 / 21.7.0 ([CVE-2024-27980][cve], April 2024), child_process.spawn('<file>.cmd', ...) synchronously throws EINVAL unless shell: true is passed.

Claude Code's Ctrl+G handler effectively does spawn(process.env.EDITOR, [tempPath]) without shell: true. When $EDITOR resolves to a .cmd path, Node rejects the spawn; the exception is caught and surfaced via the status line.

[cve]: https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2

Suggested fix

One-line change in the Ctrl+G editor-launch code:

// current
spawn(editor, args)

// option 1
spawn(editor, args, { shell: true })

// option 2 (preferred — avoids shell metacharacter pitfalls)
spawn('cmd', ['/c', editor, ...args])

Is this a regression?

Not directly — but the workaround recommended in the closed issue #29406 ("wrap your editor in a .cmd") is exactly what this bug now blocks, so for users following that advice it manifests as a silent regression.

Last Working Version

N/A (the underlying Node mitigation has been live since April 2024; this path was likely never exercised against post-CVE Node on Windows with a .cmd $EDITOR).

Claude Code Version

2.1.132

Platform

Anthropic API

Operating System

Windows 11

Terminal/Shell

Reproduces in any Windows console (Windows Terminal + PowerShell, cmd.exe, Git Bash). Independent of the host shell, because the failure is in Claude Code's own spawn call, not the shell.

Additional Information

Adjacent closed issues — same root-cause family. The LSP-spawn path received the shell: true fix, but the Ctrl+G / $EDITOR path apparently didn't:

  • #27061 — LSP plugins ENOENT, missing shell: true for .cmd
  • #51191 — typescript-lsp ENOENT on .cmd shims
  • #53814 — LSP fails to spawn npm-installed .cmd binaries
  • #17136, #19536 — earlier TypeScript-LSP variants
  • #29406 — $EDITOR paths with spaces on Windows. The accepted workaround in that thread is what this bug now blocks.

Possibly related:

  • #48950 — "Open exited with code 1" on macOS. Different platform and root cause (compound $EDITOR parsing) but the same error-message template; both may benefit from an editor-invocation refactor.
  • #51363 — Ctrl+G external editor on Windows: arrow-key forwarding (different bug, same surface).

Reproduced 2026-05-05 on Windows 11 / Node v25.4.0.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗