Skip to content

[BUG] Windows: internal PID-verification PowerShell probe (1000ms timeout) leaves permanently unkillable zombie processes that lock the project directory #80769

Description

@eking7507-pixel

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?

Title: Windows: internal PID-verification PowerShell probe (1000ms timeout) leaves permanently unkillable zombie processes that lock the project directory

Environment:

  • Claude Code v2.1.218 (native install, claude.exe)
  • Windows 10 Pro 10.0.19045
  • Windows PowerShell 5.1 (default powershell.exe)

What happens:
Claude Code internally spawns a PID-reuse verification probe:

powershell.exe -NoProfile -Command "(Get-CimInstance Win32_Process -Filter \"ProcessId=<pid>\").CreationDate.Ticks"

with {timeout: 1000} (bundled JS, function c5e / caller Wjr; there is also a
[DateTimeOffset]::new(...CreationDate).ToUnixTimeMilliseconds() variant).

On a loaded machine — e.g. several Claude Code sessions launching at once —
PowerShell 5.1 cold start regularly exceeds 1000ms. The timeout then calls
TerminateProcess while the child is still initializing (blocked in the
conhost/condrv connect, a non-alertable kernel wait). The child becomes a
permanent zombie: 1 thread in Executive wait state, ~23 handles, and it
keeps an open handle to its working directory — which is the Claude session's
project folder. The folder is then locked (cannot be renamed/moved/deleted)
until a true reboot. The paired conhost.exe is orphaned too.

Observed at scale: 11 such zombies accumulated over 3 days on one machine
(all identical command lines, all parents dead, each pinning the project
directory of the session that spawned it).

Kill behavior (the confusing part):

  • taskkill /F /PID <pid>ERROR: ... Reason: There is no running instance of the task.
  • Stop-Process -Force (elevated too) → no error, process remains
  • Win32 enumeration (Get-Process, Get-CimInstance Win32_Process) and
    Sysinternals handle.exe still show the process
  • Killing the paired conhost does not release it
  • Only a full kernel-cycle reboot clears them

Why it matters: project folders (user data) get locked for days; users
burn hours on taskkill/elevation attempts that cannot work; the orphans
accumulate silently because nothing reaps them.

What Should Happen?

  1. Raise the probe timeout well above PS 5.1 cold-start worst case, or retry
    instead of hard-killing a child that is still in process initialization.
  2. Spawn probes in a Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
  3. Spawn probes with cwd = a temp/system dir, NOT the project directory, so a
    stuck probe can never pin user data.
  4. Prefer a native API (NtQuerySystemInformation / GetProcessTimes on an
    opened handle) over shelling out to PowerShell for process creation time.

Error Messages/Logs

Steps to Reproduce

launch 4+ Claude Code sessions simultaneously on a
cold-booted Windows 10 machine with default PS 5.1; inspect
Get-CimInstance Win32_Process -Filter "Name='powershell.exe'" for
CreationDate.Ticks command lines whose parents are dead; check locked
project dirs with handle.exe <folder>.

Claude Model

Other

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

Claude Code v2.1.218

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

Title: Windows: internal PID-verification PowerShell probe (1000ms timeout) leaves permanently unkillable zombie processes that lock the project directory

Environment:

  • Claude Code v2.1.218 (native install, claude.exe)
  • Windows 10 Pro 10.0.19045
  • Windows PowerShell 5.1 (default powershell.exe)

What happens:
Claude Code internally spawns a PID-reuse verification probe:

powershell.exe -NoProfile -Command "(Get-CimInstance Win32_Process -Filter \"ProcessId=<pid>\").CreationDate.Ticks"

with {timeout: 1000} (bundled JS, function c5e / caller Wjr; there is also a
[DateTimeOffset]::new(...CreationDate).ToUnixTimeMilliseconds() variant).

On a loaded machine — e.g. several Claude Code sessions launching at once —
PowerShell 5.1 cold start regularly exceeds 1000ms. The timeout then calls
TerminateProcess while the child is still initializing (blocked in the
conhost/condrv connect, a non-alertable kernel wait). The child becomes a
permanent zombie: 1 thread in Executive wait state, ~23 handles, and it
keeps an open handle to its working directory — which is the Claude session's
project folder. The folder is then locked (cannot be renamed/moved/deleted)
until a true reboot. The paired conhost.exe is orphaned too.

Observed at scale: 11 such zombies accumulated over 3 days on one machine
(all identical command lines, all parents dead, each pinning the project
directory of the session that spawned it).

Kill behavior (the confusing part):

  • taskkill /F /PID <pid>ERROR: ... Reason: There is no running instance of the task.
  • Stop-Process -Force (elevated too) → no error, process remains
  • Win32 enumeration (Get-Process, Get-CimInstance Win32_Process) and
    Sysinternals handle.exe still show the process
  • Killing the paired conhost does not release it
  • Only a full kernel-cycle reboot clears them

Why it matters: project folders (user data) get locked for days; users
burn hours on taskkill/elevation attempts that cannot work; the orphans
accumulate silently because nothing reaps them.

Suggested fixes:

  1. Raise the probe timeout well above PS 5.1 cold-start worst case, or retry
    instead of hard-killing a child that is still in process initialization.
  2. Spawn probes in a Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
  3. Spawn probes with cwd = a temp/system dir, NOT the project directory, so a
    stuck probe can never pin user data.
  4. Prefer a native API (NtQuerySystemInformation / GetProcessTimes on an
    opened handle) over shelling out to PowerShell for process creation time.

Repro sketch: launch 4+ Claude Code sessions simultaneously on a
cold-booted Windows 10 machine with default PS 5.1; inspect
Get-CimInstance Win32_Process -Filter "Name='powershell.exe'" for
CreationDate.Ticks command lines whose parents are dead; check locked
project dirs with handle.exe <folder>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions