[BUG]
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?
Title
[BUG] [Windows] Claude Desktop leaks hung git diff --numstat (empty-tree) processes — hundreds accumulate on a large repo
Body
Environment
- Windows 11 Pro (build 10.0.26200)
- Claude Desktop 1.30096.1.0 (Microsoft Store / WindowsApps install)
- Embedded Claude Code CLI 2.1.229
- Git for Windows (
C:\Program Files\Git) - Repository: very large enterprise monorepo (60+ module folders, mixed .NET/React), working directory on a mapped drive
Symptom
While a Claude Code session is open on this repo, git.exe processes accumulate steadily (~8 per minute) and never exit. Within ~34 minutes we had 265 live git.exe processes, each with its own conhost.exe (309 conhosts total), all running the identical command:
git.exe -c core.quotepath=false -c safe.directory=* -c core.fsmonitor=false -c branch.autoSetupMerge=false diff --no-textconv --numstat -M 4b825dc642cb6eb9a060e54bf8d69288fbee4904
i.e. a rename-detecting numstat diff of the whole working tree against the empty tree hash — presumably the app's changed-files/line-count stats poll.
Observations from a WMI process snapshot:
- 263 of the 265 had a dead parent (orphaned). One had the live Claude Desktop main process as parent (the most recent spawn), one was a
cmd\git.exewrapper→git.exepair. - Accumulation survived an app restart: creation timestamps spanned a Claude Desktop restart; both the previous and the new instance kept spawning them.
- The processes sit forever at ~0% CPU. On a large monorepo this diff produces enormous output; the pattern is consistent with the spawner never draining stdout (full pipe ⇒ git blocks on write) and never timing out or killing the child.
Impact
- Hundreds of leaked
git.exe+conhost.exeprocesses per hour of session time; process-table and handle pressure grows unbounded. - Related but distinct from #49628 (exponential
git --versionself-replication) and #47306 (gitDiff exclusion retry exceeding ENAMETOOLONG): here the growth is linear, the command is the empty-tree numstat diff, and the processes are simply never reaped.
Workaround
Killing the hung processes is safe (the command is read-only):
Get-CimInstance Win32_Process -Filter "Name='git.exe'" |
Where-Object { $_.CommandLine -match 'diff --no-textconv --numstat -M 4b825dc' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
Their orphaned conhost.exe windows exit with them.
Additional context
The same session snapshot also showed a previously-closed Claude Code session that had left an orphaned bash.exe chain still running a dotnet build (with ~15 MSBuild dotnet.exe nodes and a VBCSCompiler.exe) whose output nobody would ever collect — similar in spirit to #58565 (session teardown does not reap child process trees on Windows).
What Should Happen?
The stats poller should reap or time out its git diff children (and drain stdout), and closing a session should terminate its process tree.
Error Messages/Logs
Steps to Reproduce
We don't have a minimal repro, but the trigger conditions we observed are clear:
- On Windows 11, install Claude Desktop (Store build 1.30096.1.0) with Git for Windows on PATH.
- Open a Claude Code session on a very large monorepo (ours: 60+ project folders, mixed .NET/React, ~100k+ files, working copy on a mapped network drive) with uncommitted changes present.
- Leave the session open and work normally for ~30 minutes.
- Watch the process table (e.g.
Get-Process git | Measure-Object): git.exe processes running
git diff --no-textconv --numstat -M 4b825dc642cb6eb9a060e54bf8d69288fbee4904
accumulate at roughly 8/minute and never exit, each with its own conhost.exe.
- Restart Claude Desktop — accumulation continues in the new instance; the old processes remain (orphaned, ~0% CPU) until killed manually.
Two details worth keeping in there because they likely matter for reproduction: the repo size (the empty-tree numstat diff produces enormous output, which is presumably why the child blocks — a small repo may never show this) and the mapped/network drive working copy, which makes the diff slower still.
If the form also has an "Expected behavior" field: the poller should reap or time out its git diff children and drain their stdout; git processes should never outlive the session that spawned them.
Claude Model
Other
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.229
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗