[BUG] Windows: idle sessions spin at ~1 core after a branch switch deletes the project's .claude/ — #77983 still reproduces on 2.1.280
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?
On Windows, an idle Claude Code session spins at ~1.1 cores indefinitely once the .claude/ directory in its working directory is deleted — which a plain git checkout does whenever the target branch doesn't track .claude/. It never recovers on its own: checking the original branch back out recreates .claude/ seconds later, but the process stays bound to the deleted directory until it is killed.
This is the libuv fs.watch dead-handle loop analysed in #77983 (same signature, see below). That issue was closed by the stale bot, not fixed, and the bug still reproduces on 2.1.280. The trigger here is more common than the ~/.claude/tasks cleanup described there: any repo that keeps its Claude config on some branches but not on others (e.g. on a local-only branch) and switches branches in the same working copy hits it — and it hits every session open in that working copy at once, including the one that ran the checkout.
Observed on 2026-09-23, Claude Code 2.1.280 as bundled by Claude Desktop 2.2553.13.0 (Code tab), Windows 10 Pro 22H2 (build 19045), NTFS:
- 5 idle sessions in two repos, each at 105–115 % of one core: one thread at ~85 %, ~178,000 "Other" I/O operations per second, zero read/write operations, no API traffic. Together ~5.5 of 12 logical cores; the oldest had been spinning for ~7 hours.
- Each spinning
claude.exeholds a handle toC:\$Extend\$Deleted\<file id>(Sysinternalshandle -p <pid>). Healthy sessions in repos that have.claude/hold a live handle to<repo>\.claudeinstead. - In both repos the creation time of the recreated
.claudedirectory equals the reflog entrycheckout: moving from <branch without .claude> to <branch with .claude>to the second. Every session alive in that working copy at that moment spins; a session started after one such switch stayed healthy until the next one. - Killing the spinning
claude.exeis the only remedy found; the session transcript stays intact.
What Should Happen?
An idle session should stay near 0 % CPU. Deleting a watched directory should end or re-establish the watch (with backoff) instead of putting the watcher into an endless retry loop, and recreating the directory should make the watch work again.
Error Messages/Logs
No error is logged; the loop is silent. Evidence from the live processes:
handle -p <spinning pid>
File C:\$Extend\$Deleted\002800000018E2B67E6E359A
File C:\dev\<repo>
handle -p <healthy pid, repo that has .claude/>
File C:\dev\<repo>\.claude
File C:\dev\<repo>
Per-process sample over ~10 s (Win32 I/O counters, per-thread CPU):
spinning: CPU 114 % of one core, 28 threads, busiest thread 83 %, I/O per s: read=0 write=0 other=180,219
healthy: CPU 0.5 % of one core, busiest thread 0 %, I/O per s: read=0 write=0 other=40
Steps to Reproduce
- Take a git repo where
.claude/is tracked on branchAbut not on branchB(e.g. Claude config committed only to a local branch). - With
Achecked out, open a Claude Code session in that working copy and let it go idle. (Observed with sessions started from Claude Desktop's Code tab; the process that spins is the bundledclaude.exe.) - In the same working copy run
git checkout B, thengit checkout A. - The session's
claude.exenow uses ~1 core indefinitely, andhandle -p <pid>shows a handle intoC:\$Extend\$Deleted\.
Per #77983 the trigger is any permanent (POSIX) delete of a watched directory, so step 3 can likely be shortened to Remove-Item -Recurse .claude; I have not verified that variant.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.280 (bundled by Claude Desktop 2.2553.13.0)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
_No response_