symlinkDirectories causes silent worktree cleanup failure
Description
When worktree.symlinkDirectories is configured in .claude/settings.json (e.g., to symlink node_modules), the automatic worktree cleanup on session exit silently fails because git worktree remove refuses to remove a worktree containing untracked files (the symlinks).
Steps to Reproduce
- Configure worktree symlinks in
.claude/settings.json:
``json``
{
"worktree": {
"symlinkDirectories": ["node_modules"]
}
}
- Start a session with
--worktree - Make changes, commit, push, create PR
- End the session / let it exit
Expected Behavior
The worktree should be cleaned up (or the user prompted) on session exit.
Actual Behavior
git worktree remove fails silently with:
fatal: '.' contains modified or untracked files, use --force to delete it
The symlinked node_modules directory is untracked, causing git worktree remove (without --force) to refuse. Worktrees accumulate over time.
Workaround
A WorktreeRemove hook that uses --force:
{
"hooks": {
"WorktreeRemove": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.path // empty' | { read -r wt; [ -n \"$wt\" ] && git worktree remove --force \"$wt\" 2>/dev/null; git worktree prune 2>/dev/null; } || true"
}
]
}
]
}
}
Suggested Fix
When symlinkDirectories is configured, the built-in worktree cleanup should either:
- Use
--force(since the symlinks were created by Claude Code itself) - Remove the symlinks before calling
git worktree remove - Recognize that symlinked directories are expected untracked content
Environment
- macOS Darwin 25.3.0
- Claude Code CLI
- pnpm monorepo with
node_modulessymlinked to avoid duplicating ~500MB per worktree
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗