Worktree checkout fails on Windows: checkout.workers=8 races and corrupts checkout (Background full checkout failed: other)

Status Open
Maintainer reply None cached
Activity 1 comment · opened Sep 4, 2026

"Worktree" checkbox fails on Windows: parallel checkout.workers races and corrupts checkout

Summary

Starting a session with the Worktree option enabled fails every time on this machine with:

Couldn't switch branches Background full checkout failed: other

The underlying cause is that the desktop app runs the worktree's full checkout with a hardcoded
-c checkout.workers=8. On this repo, on Windows, that parallel checkout reliably races while
creating a directory, aborts, and leaves the worktree half-populated. Serial checkout
(checkout.workers=1) succeeds every time with the identical command otherwise.

Environment

  • OS: Windows Server 2025 Standard 10.0.26100
  • git version 2.53.0.windows.2
  • git-lfs 3.7.1 (installed, but not used by this repo — no paths tracked)
  • Repo size: ~15 GB working tree (Services/ is one of ~35 top-level projects in a large multi-project .NET solution)
  • Windows Defender exclusion added for the repo path (Add-MpPreference -ExclusionPath ...) — no effect, confirming this is not an antivirus/file-lock issue

Steps to reproduce

Reproducible with plain git, entirely outside the app:

cd <repo>
git worktree add --no-checkout ../wt-repro HEAD
cd ../wt-repro
git -c core.longpaths=true -c checkout.workers=8 checkout HEAD -- . ":(exclude).claude"

Result (every time):

warning: unable to unlink 'Services': Directory not empty
fatal: cannot create directory at 'Services': Directory not empty

Inspecting the half-written worktree afterward shows some top-level directories (e.g. .githooks,
part of Services/Tertios.MailProcessor/...) already materialized — i.e. several parallel checkout
workers had already written files before the worker handling Services hit the race and the whole
checkout aborted.

Control test — identical command, only checkout.workers changed:

git worktree remove --force ../wt-repro
git worktree add --no-checkout ../wt-repro2 HEAD
cd ../wt-repro2
git -c core.longpaths=true -c checkout.workers=1 checkout HEAD -- . ":(exclude).claude"

Exits 0, full checkout succeeds, every time.

Relevant app log (from %LOCALAPPDATA%/Claude/logs/main.log)

[info] Creating worktree for session local_... from <repo>
[info] [stageCheckout] Selective checkout done in 76ms (3 paths)
[info] Created worktree "..." at <repo>\.claude\worktrees\... (prep=111ms fetch=0ms/throttled add=64ms stage1=76ms git_spawns=11)
[info] Starting local session local_... in <repo>\.claude\worktrees\...
[info] Configured worktree hooks path to <repo>\.githooks (from base repo config)
[error] Git command failed: git -c core.longpaths=true -c checkout.workers=8 checkout HEAD -- . :(exclude).claude
  { code: 128, stderr: "warning: unable to unlink 'Services': Directory not empty\nfatal: cannot create directory at 'Services': Directory not empty\n" }
[warn] [CCD] first-turn init failed after worktree creation; removing orphaned worktree for local_...
[warn] Removing worktree "..." despite uncommitted changes at <repo>\.claude\worktrees\... (caller marked it never-used)
[error] Git command failed: git -c core.longpaths=true worktree remove --force <repo>\.claude\worktrees\...
  { code: 255, stderr: "error: failed to delete '...': Permission denied\n" }
[warn] Git worktree remove failed, will try manual cleanup: ...
[error] Failed to remove worktree directory EBUSY: resource busy or locked, rmdir '<repo>\.claude\worktrees\...'
[info] Removed worktree "..."

The follow-up worktree remove --force and directory rmdir also fail (Permission denied /
EBUSY) on the same half-written directory, which is consistent with the aborted parallel checkout
leaving a file handle or partially-written entry behind under Services/ — not with an external
process (no AV, backup, or sync agent found to be involved; ruled out with a Defender exclusion and
process inspection).

This reproduced identically across 4 separate session attempts (different worktree names/dates),
always failing on the same top-level directory (Services) in this repo — i.e. it's a deterministic
repo-specific race, not a one-off fluke.

Impact

The Worktree option cannot be used at all on this repo/machine — every attempt fails and the
session never starts. Workaround is to not use the Worktree option.

Suggested fix

  • Don't hardcode checkout.workers=8 for the worktree full-checkout step; either make it configurable,

fall back to serial (checkout.workers=1) on failure and retry, or drop the flag and let git's own
checkout.workers config/auto-detection decide.

  • At minimum, retry the checkout once with checkout.workers=1 before giving up and surfacing

"Background full checkout failed: other" to the user — this alone would have avoided the failure
in all 4 observed attempts.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗