Windows: Bash tool commands auto-backgrounded on timeout are never cleaned up when the session ends, allowing orphaned processes to leak OS handles/kernel pool for days
Title
Windows: Bash tool commands auto-backgrounded on timeout are never cleaned up when the session ends, allowing orphaned processes to leak OS handles/kernel pool for days
Environment
- OS: Windows 11 Pro 10.0.26200
- Claude Code CLI, Bash tool (Git Bash / MSYS2 backend)
Summary
When a Bash tool command exceeds its timeout, it is (per documented behavior) moved to a background task rather than killed. If the Claude Code session that launched it ends (window closed, session finished) before that background command is explicitly stopped, the underlying Windows process is orphaned — Windows does not clean up orphaned children on parent/session exit. If the backgrounded command itself is one that can hang indefinitely (e.g., a recursive filesystem search), it keeps running unsupervised for as long as the machine stays up, silently consuming resources with no owner left to report on it or kill it.
Concrete repro / observed impact
We found six orphaned C:\Program Files\Git\usr\bin\find.exe processes, launched via the Bash tool with commands like:
find / -iname *lightsail*
find / -ipath *pgvector* -iname *.dll
find / -iname Swashbuckle.AspNetCore.SwaggerGen.dll
These had been running continuously since Aug 27–31 (up to 11 days) with their parent shell processes already exited. find / under Git Bash walks the entire C: drive; on Windows this can enter a reparse-point/junction cycle (OneDrive, WSL interop mounts, Docker Desktop data dirs, AppData junctions) and never terminate.
By the time we found them:
- System-wide OS handle count: 61,252,162 (a healthy baseline is ~50,000–500,000)
- Each of the six
find.exeprocesses individually held ~10–11 million handles, while using only ~6 MB of working set memory each - Kernel Paged Pool: ~20.8 GB (confirmed via both
Win32_PerfFormattedData_PerfOS_Memoryand the raw\Memory\Pool Paged Bytesperformance counter, ruling out a WMI reporting artifact) - System was at 98% overall memory utilization with 0 MB free, with Windows' Memory Compression (5.8 GB) additionally masking the pressure
- Killing the six PIDs immediately dropped system-wide handles to ~247,000 and the paged pool began draining in real time, confirming these processes were the cause
We also directly observed the backgrounding mechanism mid-investigation: a separate Bash tool command (a Win32_Product WMI query piped to tail) exceeded its 120s timeout and was automatically moved to background during this same session — reproducing the exact mechanism that (we infer) originally orphaned the find processes over a week earlier.
Why this matters
This isn't a leak in find.exe or Git for Windows — it's that the Bash tool's timeout→background behavior has no corresponding cleanup guarantee. Any long-running or potentially-hanging command a session backgrounds and then forgets about (session ends, or the agent simply never revisits it) becomes a permanent, unsupervised process. On Windows specifically, an unbounded filesystem walk hitting a reparse-point cycle is a very easy way to trigger pathological handle growth, and the resulting kernel pool exhaustion degrades the entire machine, not just the Claude Code session — 98% memory utilization system-wide with only ~12 GB attributable to the user's actual interactive session.
Suggested fix directions
- Track PIDs of auto-backgrounded Bash commands per session and terminate them when the session/window ends, rather than leaving them fully detached
- Surface a periodic reminder/warning when a backgrounded command has been running far beyond a reasonable multiple of its original timeout
- Consider a hard ceiling (e.g., wall-clock or handle-count based) that force-kills a backgrounded command that appears to have hung rather than merely being slow
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗