[FEATURE] EnterWorktree should refuse or auto-uniquify a contested worktree path

Open 💬 1 comment Opened Jun 25, 2026 by krishnaglick

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

EnterWorktree does not detect when its target worktree path is already a live worktree owned by another Claude Code session. When two concurrent sessions independently derive the same worktree name for the same unit of work — common in parallel-worktree and fleet workflows, or two people on one repo — both calls resolve to the same .claude/worktrees/<name> directory and worktree-<name> branch. The second call attaches to or collides with the first session's worktree instead of failing.

The result is cross-session entanglement: one session's edits land in the other's working tree. Worse, a session that then "retargets" with git branch -m plus git reset --hard renames the other session's checked-out branch out from under it and destroys its uncommitted work. We hit this in practice — a retarget on a contested name wiped a sibling session's in-flight changes.

This cannot be fixed from inside a repo: EnterWorktree is a built-in harness tool (no repo code path), there is no WorktreeCreate hook event to intercept, and a PreToolUse hook can only allow or block — it cannot rewrite the worktree path argument. The fix has to live in the harness.

Expected behavior

Before creating or attaching, EnterWorktree should check git worktree list for the target path. If it is already a registered worktree, either:

  • (a) Refuse with a clear error naming the existing worktree (safer default), or
  • (b) Auto-uniquify by appending a suffix (-2, a short session id) and return the actual path used (more ergonomic for fleet workflows).

Proposed Solution

Add a collision pre-check to EnterWorktree, before it creates or attaches to any worktree.

1. Detect. Run git worktree list --porcelain and resolve the requested target path against the registered worktrees (canonicalize both sides — absolute path, symlinks, trailing slash — so ./x and /repo/x compare equal). A match means the path is already a live worktree.

2. Resolve. On a match, pick one of two modes via a parameter (e.g. on_collision: "refuse" | "uniquify", default "refuse"):

  • refuse — fail with a clear error naming the existing worktree path and its checked-out branch, so the caller knows exactly what it collided with and can choose a new name. Safer default; no silent attach.
  • uniquify — append a suffix (-2, -3, … or a short session id) until the path is free, create that, and return the actual path used in the tool result so the caller operates on the real location. Ergonomic for fleet/parallel workflows that derive deterministic names.

3. Never destructive. EnterWorktree must not git branch -m or git reset --hard an existing worktree's branch as part of "retargeting." Mutating a branch another session has checked out is the actual data-loss path — the pre-check exists to make that unreachable.

Notes

  • Pure pre-flight check, no change to the happy path (free target → behaves exactly as today).
  • git worktree list is the source of truth; no extra lock files or harness-side state needed.
  • Optionally surface the chosen mode + final path in the result so fleet orchestrators can log which session got which worktree.

Alternative Solutions

I've built an entire tool to help with collision management and it's still happening, though way less frequently. This is what Opus recommends.

Priority

Medium - Would be very helpful

Feature Category

Interactive mode (TUI)

Use Case Example

_No response_

Additional Context

_No response_

View original on GitHub ↗

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