[BUG] apikeyhelper script not getting terminated on exit

Resolved 💬 3 comments Opened May 11, 2026 by nuernber Closed Jun 11, 2026

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

  1. Save this test test_ctrl_c_repro.bat script 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
  1. 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)

  1. 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.

  1. Hit Ctrl-C while it's running or just type exit and quite Claude Code

The Claude Code process should stop, but...

  1. Check if Python is still running:

``powershell
Get-NetTCPConnection -LocalPort 8888
``
You'll see the Python process still holding port 8888

  1. 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:

  1. Propagate termination signals to all child processes (recursively)
  2. Wait briefly for graceful shutdown
  3. Force-kill any processes that don't exit
  4. 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_EVENT or use TerminateProcess when 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_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗