Windows npm launcher can force-kill Codex on Ctrl+C before the resume hint is printed
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Environment
- Windows, PowerShell, npm installation of @openai/codex 0.154.0
- Node.js v24.14.1
- Entry point: codex.ps1 -> node -> codex/bin/codex.js -> codex.exe
User reproduction
- Start an interactive Codex CLI conversation and exchange messages.
- Exit with two Ctrl+C presses.
- Observe that the final resume command/session ID is missing.
- Exit another conversation with
/exit: the resume command appears normally.
The user observed the Ctrl+C behavior across multiple sessions over several days.
The first affected version has not been established.
Suspected causal path and isolated reproduction
The npm launcher forwards SIGINT via child.kill(signal). On Windows, this
force-terminates the process; it does not deliver a catchable POSIX SIGINT.
A console Ctrl+C event is already broadcast to processes attached to the console.
The additional kill can prevent the native child from completing its exit work.
Reference: https://nodejs.org/api/child_process.html#subprocesskillsignal
test_windows_signal.py exercises a copy of the installed launcher, replacing
only its executable resolver with Node and using a controlled child fixture. The
fixture records receiving SIGINT, then waits 250 ms before recording its graceful
exit summary. A separate helper sends a Windows CTRL_C_EVENT to the test's private
hidden console. It never signals the user's existing console or Codex process.
Results on this machine:
| Case | Exit code | Child receives Ctrl+C | Graceful summary |
|---|---|---|---|
| Original launcher | 1 | Yes | Missing |
| Patched launcher | 0 | Yes | Present |
| Patched normal exit | 0 | N/A | Present |
| Patched child error exit | 7 | N/A | N/A |
This reproduces the launcher-level termination bug. It is not an automated
end-to-end replay of the user's real Codex TUI session.
Proposed minimal change
At the start of forwardSignal, let the attached Windows child process handle
the console SIGINT directly, and wait for its existing exit handler:
if (process.platform === "win32" && signal === "SIGINT") {
return;
}
Other signals and non-Windows behavior remain unchanged. Upstream should also
verify console-mode restoration and Ctrl+C exit behavior in a real Windows TUI.
Logs
No logs, transcript attachments, credentials, or private session IDs are included.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the npm launcher entry point and its forwardSignal handler, then read test_windows_signal.py and its controlled child fixture. Verify the Windows Ctrl+C case preserves the child's graceful exit summary while normal exits, child-error exits, other signals, and non-Windows behavior remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100