[BUG] git worktree creation produces destructive delete-all-files commits when repo uses git-crypt
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?
When Claude Code creates a worktree (git worktree add) for a repo that uses git-crypt, and the smudge filter fails because git-crypt hasn't been unlocked in the new worktree, the resulting worktree branches contain destructive commits that show every file in the repository as deleted.
Multiple failed worktree creation attempts each leave behind a branch (e.g. claude/busy-tesla, claude/peaceful-darwin) where git status shows all files as D (deleted). These branches persist in the repo and could be accidentally pushed.
Steps to reproduce
- Have a repo with git-crypt enabled (some files encrypted via git-crypt, e.g. CLAUDE.md files)
- Start a Claude Code session that triggers worktree creation (e.g. via Dispatch/Cowork
start_code_task, or any session that uses worktree isolation) - The worktree creation fails with:
git-crypt: Error: Unable to open key file - have you unlocked/initialized this repository yet? - Observe the resulting worktree branches — they contain commits that delete every file in the repository
Impact
- Each failed attempt creates a new branch with destructive delete-all commits
- These branches are left behind and not cleaned up automatically
- If accidentally pushed, they could cause confusion or data loss for collaborators
- The user has to manually clean up stale worktrees and branches
What Should Happen?
- If the git-crypt smudge filter fails during worktree checkout, the worktree creation should fail cleanly without creating a branch that deletes all files.
- Failed worktree attempts should be cleaned up automatically (both the worktree directory and the branch).
- Ideally, Claude Code should detect git-crypt repos and either: (a) run
git-crypt unlockin the new worktree if the key is available, or (b) fall back to working in the existing checkout instead of creating a worktree.
Error Messages/Logs
Failed to start code session: Background full checkout failed for /Users/jdelamaza/AIA/.claude/worktrees/busy-tesla: git-crypt: Error: Unable to open key file - have you unlocked/initialized this repository yet?
error: external filter '"git-crypt" smudge' failed 1
error: external filter '"git-crypt" smudge' failed
fatal: health/CLAUDE.md: smudge filter git-crypt failed
Steps to Reproduce
- Have a repository that uses git-crypt with some encrypted files (e.g. CLAUDE.md files)
- Ensure git-crypt is unlocked in the main checkout (working normally day-to-day)
- Start a Claude Code session that uses worktree isolation (e.g. via Dispatch/Cowork
start_code_task, or any session mode that callsgit worktree add) - The session fails to start because the git-crypt smudge filter can't find the key in the new worktree
- Check the branches created:
git branch | grep claude/— each failed attempt leaves a branch - Check any of those branches:
git logandgit statusshow all files deleted
In our case, 3 failed attempts created 3 separate worktree branches, each with destructive delete-all-files commits.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Latest (via Cowork/Dispatch)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
This was triggered via Cowork/Dispatch mode in the Claude Desktop App, which uses start_code_task to create isolated worktree sessions for code tasks.
The root cause is that git worktree add triggers git-crypt's smudge filter on encrypted files, and since the new worktree hasn't had git-crypt unlock run, the filter fails. However, instead of failing cleanly, the worktree ends up in a state where all files appear deleted.
Note: The main checkout works fine with Claude Code directly (VS Code, terminal, Claude Desktop) because those sessions use the existing checkout where git-crypt is already unlocked. The issue is specific to worktree-based isolation.
A post-checkout git hook was attempted as a workaround, but since the smudge filter runs during checkout (before post-checkout fires), it didn't help initially. The workaround that eventually worked was configuring git-crypt to auto-unlock at a different stage.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗