[BUG] apikeyhelper script not getting terminated on exit
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Issue
On Windows, when Claude Code spawns a .bat batch file script for the apikeyhelper, if the user does exit or ctrl-c before the apikeyhelper is finished (e.g., doing an interactive SSO login), Claude Code does NOT terminate the .bat child process. The process becomes orphaned and continues running. ~~This appears to only be an issue on Windows, no Mac/Linux.~~ UPDATE: this may occur on linux as well
Impact
- Orphaned processes continue holding resources (ports, file handles, etc.)
- Users must manually kill processes with Task Manager or PowerShell
- Particularly problematic for long-running processes like HTTP servers
What Should Happen?
If the user either does exit or sends ctrl-c to Claude Code, any child processes (in this case the script running in apikeyhelper) should be terminated as well.
Error Messages/Logs
Steps to Reproduce
Reproduction Steps
- Save this test
test_ctrl_c_repro.batscript somewhere accessible by Claude Code:
@echo off
REM Minimal reproduction of Windows Ctrl-C propagation issue in Claude Code
REM
REM ISSUE: When Claude Code calls this batch file and you hit Ctrl-C in Claude,
REM the Python child process does NOT receive the signal and keeps running.
REM
REM TO REPRODUCE:
REM 1. In Claude Code, ask: "run test_ctrl_c_repro.bat"
REM 2. Hit Ctrl-C in Claude Code
REM 3. Check if process still running: Get-NetTCPConnection -LocalPort 8888
REM You should see the Python process still holding the port
REM
REM EXPECTED: Python process should terminate when Claude Code is interrupted
REM ACTUAL: Python process becomes orphaned and continues running
echo Starting Python HTTP server (this simulates a login flow)...
echo.
echo Try hitting Ctrl-C in Claude Code - the Python process will NOT stop
echo (but Ctrl-C inside this window WILL work)
echo.
python -m http.server 8888
- Configure the test script as apiKeyHelper in settings.json:
Add this to your Claude Code settings.json:
``json``
{
"apiKeyHelper": "\"C:\\full\\path\\to\\test_ctrl_c_repro.bat\""
}
(Replace with the actual full path to the test_ctrl_c_repro.bat file)
- Trigger Claude Code to call the apiKeyHelper:
Start Claude Code or make an API request that requires authentication.
Claude Code will call the batch file, which starts the Python HTTP server.
- Hit Ctrl-C while it's running or just type
exitand quite Claude Code
The Claude Code process should stop, but...
- Check if Python is still running:
``powershell``
Get-NetTCPConnection -LocalPort 8888
You'll see the Python process still holding port 8888
- Clean up the orphaned process:
``powershell``
Stop-Process -Id (Get-NetTCPConnection -LocalPort 8888).OwningProcess -Force
Expected Behavior
When Claude Code receives Ctrl-C or exit, it should:
- Propagate termination signals to all child processes (recursively)
- Wait briefly for graceful shutdown
- Force-kill any processes that don't exit
- Then exit itself
Root Cause
Windows doesn't automatically propagate signals to child processes like Unix/Linux does. Claude Code needs to explicitly:
- Track child process PIDs
- Send
CTRL_BREAK_EVENTor useTerminateProcesswhen interrupted - OR use Windows Job Objects to ensure all children die with the parent
Workarounds
None for end users. This must be fixed in Claude Code itself.
Environment
- OS: Windows 11 Pro 10.0.26200
- Claude Code: 2.1.139
- Python: 3.13.7
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.139
Platform
AWS Bedrock
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗