Bash tool leaks orphaned child processes on Windows timeout (runaway ind / scans accumulate for hours)
Summary
On Windows, when a Bash-tool command exceeds its timeout (or otherwise ends), Claude Code terminates the bash.exe shell but not its descendant processes. Grandchild processes (e.g. find.exe under Git Bash / MSYS2) keep running as orphans. A find / full-filesystem scan therefore keeps crawling the entire disk for hours after the tool call has "ended," and these accumulate across sessions until the machine is heavily loaded.
Environment
- Claude Code: 2.1.206
- Model: Opus 4.8 (1M context)
- OS: Windows 11 Education, 10.0.22631 (build 22631)
- Shell / Bash-tool backend: Git Bash (MSYS2),
git version 2.36.1.windows.1,C:\Program Files\Git\usr\bin\find.exe
Impact
- Found 10 orphaned
find.exeprocesses alive, spawned over ~4 hours across prior sessions (creation timestamps 2026-07-09 20:09 → 2026-07-10 00:10). - Every one was scanning from filesystem root
/. - Each had accumulated 16,000–26,000 CPU-seconds (4.5–7 CPU-hours) and was still consuming ~10–19% of a core apiece when discovered — collectively saturating the machine.
- Parent
bash.exeshells were all already exited (orphanedParentProcessIdpoints to a dead PID), so nothing would ever reap them.
Leaked command lines (verbatim)
find.exe / -iname slint-1.17* -maxdepth 6
find.exe / -type d -iname slint-1.17*
find.exe / -path */registry/src/*/slint-1.1*/src/api/window.rs
find.exe / -type d -iname slint-*-examples -o -type d -path *slint*/examples
find.exe / -iname flickable.rs
find.exe / -path *registry/src*/i-slint-compiler* -maxdepth 10
find.exe / -iname midi_mapping.json
find.exe / -iname *.slint -path *examples*
find.exe / -iname *.rs -path *slint* (x2)
All are unbounded (or barely bounded) recursive scans rooted at /. On Windows/MSYS2 that walks the whole drive, which routinely exceeds the 120s Bash-tool timeout.
Reproduction
- On Windows, have Claude Code run a slow full-disk command via the Bash tool, e.g.
find / -iname somethingthat takes longer than the tool timeout. - Let the tool call time out (or otherwise end).
- Observe: the
bash.exewrapper is gone, butfind.exeis still running.Get-CimInstance Win32_Process -Filter "Name='find.exe'"shows it alive with aParentProcessIdwhose process no longer exists.
Root cause
The Bash tool does not terminate the full descendant process tree on timeout/cancel/exit on Windows — it appears to kill only the immediate bash.exe. MSYS2 grandchildren survive and keep running. There is no Job Object / process-group kill guaranteeing tree teardown.
Suggested fixes
- On Windows, launch Bash-tool commands inside a Windows Job Object with
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, so closing the job kills the entire tree on timeout/cancel/exit. - Alternatively, on timeout kill the process tree explicitly (
taskkill /T /Fon the shell PID, or enumerate + terminate descendants). - Consider warning when a Bash command roots a recursive scan at
/on Windows.
Note on killing these
For these MSYS2 processes, both taskkill /F /PID ("no instance running") and PowerShell Stop-Process ("cannot find a process") failed, even though the processes were alive and burning CPU. The WMI Win32_Process.Terminate method worked:
Get-CimInstance Win32_Process -Filter "Name='find.exe'" |
ForEach-Object { Invoke-CimMethod -InputObject $_ -MethodName Terminate }