[BUG] Desktop (Windows): worktree session fails — background full checkout dies with Directory not empty on the first top-level path; every stage1=(2 paths) run fails
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?
Summary
Starting a session with the worktree option enabled in the Claude desktop app fails before the first turn. The UI shows the generic git_checkout_failed guidance — "Commit or stash changes, or check your repository for issues like a missing branch, locked files, or Git LFS setup" — none of which applies: the working tree is clean, there are no submodules, no git-crypt, and no LFS-tracked files.
The background full checkout dies on the first tracked top-level entry it has to create:
git -c core.longpaths=true -c checkout.workers=2 checkout HEAD -- . :(exclude).claude
warning: unable to unlink '.env_project': Directory not empty
fatal: cannot create directory at '.env_project': Directory not empty
exit code 128, cwd = <repo>\.claude\worktrees\<wt>.
The failure is positional, not name-specific
The first failures landed on a tracked top-level directory named ..file_away, which sorts first by byte order. I renamed it to .file_away and committed. The next attempt failed on .env_project — the next tracked top-level entry in byte order once .claude is excluded.
So the background checkout dies on the first directory it must create, whatever that directory happens to be. That means the directory already exists, and is non-empty, at the moment the checkout runs.
Regression signal
Across every worktree creation on this machine, in all repos:
| stage 1 | runs | outcome |
| --- | --- | --- |
| Selective checkout done ... (1 paths) | 23 | all completed — Background full checkout done in 2363–5361ms |
| Selective checkout done ... (2 paths) | 4 | all failed as above |
No (2 paths) run has ever succeeded here. Last known-good CLI: 2.1.247. Failing: 2.1.258 and 2.1.260.
Log excerpt (repo path and session ids redacted)
[WorktreePool] No reusable worktree for <repo> (1/1 candidates checked, 1 known unclean)
Creating worktree for session <id> from <repo>
[stageCheckout] Selective checkout done in 245ms (2 paths)
Created worktree "<wt>" at <repo>\.claude\worktrees\<wt> (prep=196ms fetch=0ms/throttled add=102ms stage1=245ms git_spawns=11)
Starting local session <id> in <repo>\.claude\worktrees\<wt>
Copied 9 files from gitignored .claude
[error] Git command failed: git -c core.longpaths=true -c checkout.workers=2 checkout HEAD -- . :(exclude).claude { code: 128, spawnErrno: undefined, stderr: "warning: unable to unlink '.env_project': Directory not empty\nfatal: cannot create directory at '.env_project': Directory not empty\n", cwd: '<repo>\\.claude\\worktrees\\<wt>' }
[CCD] first-turn init failed after worktree creation; removing orphaned worktree for <id>
Removing worktree "<wt>" despite uncommitted changes (caller marked it never-used)
Removed worktree "<wt>"
In two of the four failures, [worktree-copy] worker forked is logged in the same second as the error.
Note on what creates the colliding directory
Per #91443, stage 1 checks out a fixed path list (.claude/** and CLAUDE.md) — which stage 2 already excludes via :(exclude).claude. So stage 1 does not appear to be what creates the colliding directory, and from outside the app I can't tell what does.
One possibility consistent with the failure always landing on the first entry: the full checkout runs concurrently with something else populating the same worktree, so both walk the sorted index from the top and collide immediately on the first directory. The [worktree-copy] worker forked line appearing in the same second is suggestive but not conclusive.
Reproduction
- On Windows, open the Claude desktop app on a normal git repo with at least one tracked top-level directory.
- Start a new session with the worktree option enabled.
- Session start aborts; log shows the checkout failure above.
Not reproducible when stage 1 logs (1 paths).
Environment
- Claude desktop 1.46388.1.0 (MSIX), Windows Server 2022 Datacenter 10.0.20348
- Claude Code CLI 2.1.260 (also reproduced on 2.1.258); last good 2.1.247
- git 2.43.0.windows.1
- Repo: ~2,200 tracked files, clean working tree, no submodules, no git-crypt, no
.gitattributesand no LFS-tracked files (git-lfs 3.4.0 installed) core.longpaths=true,core.autocrlf=true,core.ignorecase=true,core.symlinks=false,extensions.worktreeConfig=true
Not a duplicate of
- #57048 —
(0 paths)/ empty index, fails withpathspec '.' did not match any file(s). Here it is(2 paths)and fails on directory creation. - #86276 — empty HEAD tree. Not the case here.
- #74526, #55387 — require git submodules. None here.
- #58610 — git-crypt. Not used.
Closest relative: #91443 (same staged-checkout machinery, Windows, open).
Side effect
Each failed attempt leaves an orphan claude/<name> branch behind after the worktree is torn down.
Workarounds
- Disable the worktree option — in-place sessions start normally.
- Or pre-create the worktree by hand (
git worktree add <path> -b <branch>) and open a normal session in that folder. A single unstagedgit worktree addhas no such problem, which is consistent with the fault being in the staged-checkout seam rather than in worktree creation itself.
What Should Happen?
Claude should successfully create the worktree
Error Messages/Logs
Steps to Reproduce
- On Windows, open the Claude desktop app on a normal git repo with at least one tracked top-level directory.
- Start a new session with the worktree option enabled.
- Session start aborts; log shows the checkout failure above.
Not reproducible when stage 1 logs (1 paths).
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude 1.46388.1 (2dfd5f) 2026-09-04T00:17:06.000Z
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗