[BUG] Worktree session creation fails on Windows since 2.1.260: background full checkout forces checkout.workers=8
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
Closest existing issues, all different root causes: #57048 (empty index, pathspec matches nothing, macOS, closed as duplicate), #47266 / #34645 (.git/config.lock contention between concurrent worktree add calls), #57767 (Windows locks on worktree removal), #39680 (EEXIST on an existing .claude/worktrees/).
Notably, the command quoted in #57048 contains no checkout.workers flag — that flag appears to be new in 2.1.260.
What's Wrong?
Since updating to Claude Code 2.1.260 (Claude Desktop 1.46388.1), every attempt to start a session with the worktree option fails on Windows.
The app creates the worktree, runs a 4-path selective checkout, then the background full checkout fails. The worktree is torn down immediately, so nothing appears in .claude/worktrees/, and the UI shows:
Impossible de changer de branche. / Unable to switch branch. Background full checkout failed: other
The failing command is:
git -c core.longpaths=true -c checkout.workers=8 checkout HEAD -- . :(exclude).claude
The root cause is checkout.workers=8. On this machine git's parallel checkout fails deterministically to create the very first directory it writes, whatever that directory is. Reduced to a minimal synthetic repository, the behaviour is:
| checkout.workers | Result |
|---|---|
| 1 | exit 0, all files written |
| 2 | exit 128 |
| 8 | exit 128 |
This is not repo-specific. I reproduced it on three unrelated repositories, including a throwaway repo of 120 files created seconds earlier in %TEMP% that has never been touched by Claude. The failure always lands on the first directory git tries to create (alpha, deploy, archive, Documentation — whichever comes first).
There is no user-side workaround: -c on the command line overrides any git config, and checkout.thresholdForParallelism is ignored when checkout.workers is set explicitly (verified up to 99999999).
The CLI path is unaffected: claude --worktree <name>, which performs a sequential checkout via git worktree add, works perfectly on the same machine at the same minute.
What Should Happen?
The worktree session should be created, as it was in 2.1.258 and every version before it.
Ideally the background full checkout should fall back to a single worker when the parallel checkout fails, rather than tearing down the worktree and aborting the session. That alone would restore the previous behaviour.
Error Messages/Logs
# From %LOCALAPPDATA%\claude\Logs\main.log
2026-09-04 08:58:43 [info] Creating worktree for session local_078bd705-...
2026-09-04 08:58:43 [info] [stageCheckout] Selective checkout done in 181ms (4 paths)
2026-09-04 08:58:44 [info] Created worktree "ticket-xxxx-896cb5" (prep=245ms fetch=0ms/throttled add=123ms stage1=181ms git_spawns=11)
2026-09-04 08:58:44 [info] Starting local session local_078bd705-... in ...\.claude\worktrees\ticket-xxxx-896cb5
2026-09-04 08:58:44 [error] Git command failed: git -c core.longpaths=true -c checkout.workers=8 checkout HEAD -- . :(exclude).claude
{ code: 128,
stderr: "warning: unable to unlink 'Documentation': Directory not empty\n
fatal: cannot create directory at 'Documentation': Directory not empty\n" }
2026-09-04 08:58:44 [warn] [CCD] first-turn init failed after worktree creation; removing orphaned worktree
2026-09-04 08:58:44 [info] Removed worktree "ticket-xxxx-896cb5"
Steps to Reproduce
Minimal, self-contained, no Claude involved — this reproduces the exact failure the app hits:
# 1. Build a throwaway repo: 120 files in 3 directories
cd "$(mktemp -d)"
git init -q .
git config user.email t@t && git config user.name t
for d in alpha bravo charlie; do
mkdir -p "$d/sub"
for i in $(seq 1 40); do echo x > "$d/sub/f$i.txt"; done
done
git add -A && git commit -qm minimal
# 2. Reproduce the app's two-stage checkout, at 1 then 2 then 8 workers
for w in 1 2 8; do
rm -rf ../wt; git worktree prune; git branch -D wt 2>/dev/null
git worktree add --no-checkout -b wt ../wt HEAD >/dev/null 2>&1
git -C ../wt -c checkout.workers=$w checkout HEAD -- . 2>&1 | tail -1
echo "workers=$w -> exit $?"
done
Observed:
workers=1 -> exit 0
fatal: cannot create directory at 'alpha': Directory not empty
workers=2 -> exit 128
fatal: cannot create directory at 'alpha': Directory not empty
workers=8 -> exit 128
To reproduce through the product: start a new session with the worktree option enabled on Windows. It fails every time.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version.
Evidence from main.log, counting successful worktree creations per day on this machine:
| Date | Created | Failed |
|---|---|---|
| 2026-08-28 | 4 | 0 |
| 2026-08-29 | 4 | 0 |
| 2026-08-30 | 8 | 0 |
| 2026-08-31 | 6 | 0 |
| 2026-09-01 | 12 | 0 |
| 2026-09-02 | 11 | 0 |
| 2026-09-03 | 18 | 0 |
| 2026-09-04 | 8 | 8 |
43 successful worktree creations over seven days, zero failures. Then 8 out of 8 failures today.
The string checkout.workers does not appear anywhere in the log between 2026-08-28 and 2026-09-04 07:16 — it first appears at 08:34:43, after the update. Timeline:
2026-09-03 12:05 claude-code 2.1.258 installed -> 18 worktrees created that day, 0 failures
2026-09-04 07:05 [updater] Update downloaded { releaseName: 'Claude 1.46388.1' }
2026-09-04 07:16 claude-code 2.1.260 installed
2026-09-04 08:34 first failure
Nothing else changed on the machine: git was installed 2026-04-20, and a full reboot changed nothing.
Last Working Version
2.1.258
Claude Code Version
2.1.260 (Claude Code) — Claude Desktop 1.46388.1 (MSIX)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other — Claude Desktop app (the CLI in Windows Terminal is unaffected)
Additional Information
- Environment: Windows 11 Pro 10.0.26200.9168, git 2.54.0.windows.1 (installed 2026-04-20), Claude Desktop installed as an MSIX package. Windows Defender real-time protection is off; Acronis Cyber Protect filter drivers (
snapman,tib_mounter) are loaded, which may be why parallel checkout races on this machine specifically. That said, those drivers were equally loaded yesterday, when all 18 worktree creations succeeded — the trigger is the new flag, not the environment.
- Why this is worth guarding against regardless of the local cause: git's parallel checkout is opt-in and defaults to a single worker, so forcing
checkout.workers=8exposes users to a code path that sees very little real-world use. Any filesystem filter driver (AV, backup, sync client) that makes directory creation non-atomic will trip it, and the user has no way to override a-cflag.
- Suggested fix: on failure of the parallel checkout, retry once with
checkout.workers=1before tearing down the worktree. Optionally expose the worker count as a setting.
- Worth noting that the teardown is silent about the real cause: the UI text mentions LFS, locked files and missing branches, none of which apply here, which sent me a long way down the wrong path before I found the actual git command in
main.log.
3 Comments
Independent confirmation from a second Windows machine, plus a root-cause refinement and a user-side workaround that does work.
Environment
-c checkout.workers=6core.symlinks=false,extensions.worktreeConfig=trueSelective checkout done ... (2 paths)thenBackground full checkout done). After the update to 2.1.260: 8/8 failures,(3 paths), always:git -c core.longpaths=true -c checkout.workers=6 checkout HEAD -- . :(exclude).claude
warning: unable to unlink '.github': Directory not empty
fatal: cannot create directory at '.github': Directory not empty
Root-cause refinement:
checkout.workers > 1×core.fscache=trueGit for Windows ships
core.fscache=truein its system config (C:/Program Files/Git/etc/gitconfig). Replaying the app's exact two-stage sequence by hand on a fresh--no-checkoutworktree of the same repo:| stage-2 command (after
worktree add --no-checkout) | result ||---|---|
|
-c checkout.workers=6 checkout HEAD -- . ":(exclude).claude"| exit 128, 0 files (dies on the first directory) ||
-c checkout.workers=1 ...| exit 0, all files ||
-c checkout.workers=6 -c checkout.thresholdForParallelism=100000 ...| exit 128 (the setting alone triggers it, even when no parallel workers actually run) ||
-c checkout.workers=6 -c core.fscache=false ...| exit 0, all files |Same on a 7-file synthetic repo (
git init, two dirs × 3 files, nothing else):checkout.workers=2→error: unable to stat just-written file 'dir2/g3.txt': No such file or directory(exit 255);checkout.workers=2 -c core.fscache=false→ exit 0. So git's fscache is serving stale directory state to the parallel-checkout code path; "Directory not empty" and "unable to stat just-written file" are the same staleness surfacing at different points.User-side workaround (contrary to "no user-side workaround" above)
The app forces
checkout.workersvia-cbut never touchescore.fscache, so repo (or global) config wins:git config core.fscache false # in the affected repo, or --global
Verified: with only that repo-local setting changed, the app-identical command (
LC_ALL=C git -c core.longpaths=true -c checkout.workers=6 checkout HEAD -- . ":(exclude).claude") exits 0 and writes all 857 non-.claudefiles. Cost: slightly slowergit statuson Windows.Suggested fix on the app side
Pass
-c core.fscache=falsealongsidecheckout.workerson Windows (or don't raisecheckout.workerson Windows, or retry sequentially when the parallel checkout exits non-zero instead of tearing the worktree down). This is arguably also a Git for Windows bug (parallel checkout + fscache) worth reporting upstream, but the app-side guard fixes the regression for everyone now.Side effects seen here
After each failure
git worktree remove --forcehits EBUSY, leaving an empty.claude/worktrees/<slug>directory plus an orphanclaude/<slug>branch. #91973 looks like the same bug from the desktop side.Third Windows machine, plus a data point that bounds the upstream side: Git for Windows 2.55.0.windows.3 does not have this bug, with
core.fscache=truestill set.Same failure as reported — Claude Desktop 1.46388.1,
git -c core.longpaths=true -c checkout.workers=6 checkout HEAD -- . :(exclude).claude, dying on the first directory it must create (warning: unable to unlink 'X': Directory not empty/fatal: cannot create directory at 'X': Directory not empty). 19 worktree creations today, 19 failures; 26 over the preceding 10 days, zero.checkout.workersappears nowhere inmain.logbefore the update.Before and after upgrading git on the same machine, nothing else changed:
| git | core.fscache | workers=2 / workers=6 |
|---|---|---|
| 2.47.0.windows.2 | true (system config) | fails, 6/6 runs, 0 files written |
| 2.55.0.windows.3 | true (system config, untouched) | passes |
C:/Program Files/Git/etc/gitconfigstill carriesfscache = trueafter the upgrade, so this is not the installer quietly disabling it — I re-ran the repro with-c core.fscache=trueexplicitly and it passes. Since this issue reports failure on 2.54.0.windows.1 and the comment above on 2.49.0, the upstream fix looks like it landed in 2.55. Worth someone confirming 2.54 vs 2.55, because "upgrade Git for Windows" is then a complete fix rather than onlycore.fscache=false.Two smaller notes:
A smaller minimal trigger than the repros above — two files in a nested directory is enough:
Isolating the ingredients on the broken git: a flat directory with 20 files passes; a single file in
a/b/passes; it needs at least two files under a directory that itself contains a subdirectory, and an empty (--no-checkout) worktree — re-running on an already-materialized tree passes. Also confirmingcheckout.thresholdForParallelismhas no effect (set to 999999, verified visible from inside the worktree).Repo-independent. Four unrelated repos here all failed, including a fresh clone on a different drive and one with 25 tracked files. Submodules are irrelevant: repos with zero gitlinks fail, and excluding all 20 gitlinks by pathspec in the one that has them still failed.
+1 on the debris, since it compounds the confusion: every failed attempt left an orphan zero-commit
claude/<slug>-<hash>branch behind — 33 accumulated in a day here — because teardown hitsPermission deniedand thenEBUSYon the rmdir. Retrying the session mints another one each time, and the UI's "Couldn't switch branches / check for locked files or Git LFS" sends you nowhere near the real cause.Same here, reproduced on two unrelated repos.
My log shows the same
-c checkout.workers=8flag, which confirms the hypothesis:[stageCheckout] Selective checkout done in 132ms (2 paths)
git -c core.longpaths=true -c checkout.workers=8 checkout HEAD -- . :(exclude).claude
warning: unable to unlink 'app': Directory not empty
fatal: cannot create directory at 'app': Directory not empty
(exit 128) → worktree remove --force: Permission denied → rmdir EBUSY
appis a regular tree in HEAD; no submodules, symlinks or LFS. Manualgit worktree addon the same commit works.Ruled out antivirus (Kaspersky excluded + paused), IDE, dirty main checkout, stale worktree entries, reboot.
Related: #91973 (same symptom)