[BUG] Worktree session creation fails on Windows since 2.1.260: background full checkout forces checkout.workers=8

Status Open
Reported on v2.1.260
Maintainer reply None cached
Activity 3 comments · opened Sep 4, 2026

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=8 exposes 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 -c flag.
  • Suggested fix: on failure of the parallel checkout, retry once with checkout.workers=1 before 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.

View original on GitHub ↗

3 Comments

taskmemo · 20 hours ago

Independent confirmation from a second Windows machine, plus a root-cause refinement and a user-side workaround that does work.

Environment

  • Claude Desktop 1.46388.1.0 (MSIX) / Claude Code 2.1.260, Windows 11 Pro 10.0.26200 (Japanese locale)
  • Git for Windows 2.49.0.windows.1; 12 logical CPUs, so the app passes -c checkout.workers=6
  • Repo: ~900 tracked files, clean tree, no submodules / LFS; core.symlinks=false, extensions.worktreeConfig=true
  • Last success 2026-09-04 13:36 JST on 2.1.258 (Selective checkout done ... (2 paths) then Background 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=true

Git for Windows ships core.fscache=true in its system config (C:/Program Files/Git/etc/gitconfig). Replaying the app's exact two-stage sequence by hand on a fresh --no-checkout worktree 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=2error: 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.workers via -c but never touches core.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-.claude files. Cost: slightly slower git status on Windows.

Suggested fix on the app side

Pass -c core.fscache=false alongside checkout.workers on Windows (or don't raise checkout.workers on 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 --force hits EBUSY, leaving an empty .claude/worktrees/<slug> directory plus an orphan claude/<slug> branch. #91973 looks like the same bug from the desktop side.

szityi · 18 hours ago

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=true still 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.workers appears nowhere in main.log before 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/gitconfig still carries fscache = true after the upgrade, so this is not the installer quietly disabling it — I re-ran the repro with -c core.fscache=true explicitly 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 only core.fscache=false.

Two smaller notes:

A smaller minimal trigger than the repros above — two files in a nested directory is enough:

git init r && cd r
mkdir -p a/b && echo x > a/b/f1.txt && echo x > a/b/f2.txt
git add -A && git commit -qm init
git worktree add --no-checkout wt --detach HEAD
git -C wt -c checkout.workers=2 checkout HEAD -- .

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 confirming checkout.thresholdForParallelism has 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 hits Permission denied and then EBUSY on 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.

Tymur89 · 17 hours ago

Same here, reproduced on two unrelated repos.

  • Windows 11, Claude desktop 1.46388.1.0 (Microsoft Store), Git for Windows
  • CLI 2.1.258 (downloaded Sep 3 08:40 local) — worktrees worked, last success Sep 4 08:02
  • CLI 2.1.260 auto-downloaded Sep 4 08:35 — every attempt since fails identically

My log shows the same -c checkout.workers=8 flag, 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

app is a regular tree in HEAD; no submodules, symlinks or LFS. Manual git worktree add on the same commit works.
Ruled out antivirus (Kaspersky excluded + paused), IDE, dirty main checkout, stale worktree entries, reboot.

Related: #91973 (same symptom)