claude-code - 💡(How to fix) Fix [BUG] Windows: MCP child processes orphan on session exit — suggest JobObject + KILL_ON_JOB_CLOSE [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#57740Fetched 2026-05-11 03:26:40
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Timeline (top)
labeled ×3commented ×1

Error Message

PS> Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Measure-Object Count : 57

After cleanup attempts on stuck zombies:

PS> Stop-Process -Id 25956 -Force Stop-Process : Cannot stop process "node (25956)" because of the following error: Access is denied

PS> taskkill /F /PID 25956 ERROR: The process with PID 25956 could not be terminated. Reason: Access is denied.

wmic uses a different kernel API path and succeeds:

PS> wmic process where "ProcessId=25956" delete Deleting instance \DESKTOP-XXX\ROOT\CIMV2:Win32_Process.Handle="25956" Instance deletion successful.

Process inventory snapshot before cleanup (4 days of normal use):

Tag Count OldestHours AvgHours mcp-server 42 94.7 73.4 # playwright + context7 codex-cli 5 95.6 87.0 gemini-cli 2 80.0 80.0 phase-runner-orphan-chain 2 33.5 33.5 # stuck IPC chain, wmic-only kill

Root Cause

POSIX users do not see this because SIGHUP propagation handles child cleanup by default. Windows has no equivalent default — children are fully detached from parent lifecycle unless the parent explicitly opts in via JobObject + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. Claude Code currently does not.

Fix Action

Fix / Workaround

Some long-stuck orphans (33h+ in my case) enter an "uninterruptible IPC syscall" state where even Stop-Process -Force and taskkill /F return Access denied. The only workaround is wmic process where "ProcessId=N" delete (different kernel API path) or full reboot.

Code Example

PS> Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Measure-Object
  Count : 57

  # After cleanup attempts on stuck zombies:
  PS> Stop-Process -Id 25956 -Force
  Stop-Process : Cannot stop process "node (25956)" because of the following error: Access is denied

  PS> taskkill /F /PID 25956
  ERROR: The process with PID 25956 could not be terminated.
  Reason: Access is denied.

  # wmic uses a different kernel API path and succeeds:
  PS> wmic process where "ProcessId=25956" delete
  Deleting instance \\DESKTOP-XXX\ROOT\CIMV2:Win32_Process.Handle="25956"
  Instance deletion successful.

  # Process inventory snapshot before cleanup (4 days of normal use):
  Tag        Count OldestHours AvgHours
  mcp-server    42        94.7     73.4    # playwright + context7
  codex-cli      5        95.6     87.0
  gemini-cli     2        80.0     80.0
  phase-runner-orphan-chain  2  33.5  33.5  # stuck IPC chain, wmic-only kill
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

On Windows, MCP child processes (and codex/gemini plugin CLI subprocesses) survive Claude Code main process exit indefinitely. Over 4 days of normal use I accumulated 55 orphan node.exe processes consuming ~2 GB RAM:

  • 24× playwright MCP server
  • 18× context7 MCP server
  • 11× codex.js app-serve (codex@openai-codex plugin)
  • gemini-cli (gemini@google-gemini plugin)

POSIX users do not see this because SIGHUP propagation handles child cleanup by default. Windows has no equivalent default — children are fully detached from parent lifecycle unless the parent explicitly opts in via JobObject + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. Claude Code currently does not.

Some long-stuck orphans (33h+ in my case) enter an "uninterruptible IPC syscall" state where even Stop-Process -Force and taskkill /F return Access denied. The only workaround is wmic process where "ProcessId=N" delete (different kernel API path) or full reboot.

What Should Happen?

When the Claude Code main process exits (clean exit, Ctrl+C, window close, or crash), all MCP server children and plugin CLI subprocesses should terminate atomically with it — same lifecycle parity Linux/macOS users get for free via SIGHUP propagation.

After closing a session, Get-Process node should return zero Claude-Code-spawned residue.

Error Messages/Logs

PS> Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Measure-Object
  Count : 57

  # After cleanup attempts on stuck zombies:
  PS> Stop-Process -Id 25956 -Force
  Stop-Process : Cannot stop process "node (25956)" because of the following error: Access is denied

  PS> taskkill /F /PID 25956
  ERROR: The process with PID 25956 could not be terminated.
  Reason: Access is denied.

  # wmic uses a different kernel API path and succeeds:
  PS> wmic process where "ProcessId=25956" delete
  Deleting instance \\DESKTOP-XXX\ROOT\CIMV2:Win32_Process.Handle="25956"
  Instance deletion successful.

  # Process inventory snapshot before cleanup (4 days of normal use):
  Tag        Count OldestHours AvgHours
  mcp-server    42        94.7     73.4    # playwright + context7
  codex-cli      5        95.6     87.0
  gemini-cli     2        80.0     80.0
  phase-runner-orphan-chain  2  33.5  33.5  # stuck IPC chain, wmic-only kill

Steps to Reproduce

  1. Environment: Windows 11, Claude Code 2.1.132, Node v24.9.0
  2. Configure ~/.claude.json with at least 2 stdio MCP servers, e.g.:
    {
      "mcpServers": {
        "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] },
        "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp"] }
      }
    }
  3. Open Claude Code and let MCP servers initialize. Confirm with: Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Where-Object { $_.CommandLine -match 'context7|playwright' } | Measure-Object

Expect: 2 (one per MCP)

  1. Close the Claude Code window (or Ctrl+C, or kill the main process).
  2. Re-check the same query → both MCP servers still alive, now orphaned (PPID points to the dead Claude Code main process).
  3. Repeat steps 3-5 across a few days of normal use → orphans accumulate arithmetically. After ~4 days I had 42 MCP orphans + 13 plugin CLI orphans = 55 total.
  4. Some orphans reach a stuck-IPC state and refuse Stop-Process -Force / taskkill /F (Access denied). Only wmic process delete or reboot clears them.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.1.132

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING