Skip to content

[BUG] ExitWorktree (remove) reports success but orphans the worktree (dir + admin entry + branch); intermittently corrupts parent repo core.bare #69802

Description

@jsolly

Environment

  • Claude Code 2.1.177 (CLI)
  • macOS 26.5.1 (Darwin 25.5.0), git 2.50.1 (Apple Git-155)
  • worktree.baseRef: "fresh". A WorktreeCreate hook relocates worktrees out of .claude/worktrees/ to ~/code/.worktrees/<repo>/<name>/, so the session cwd becomes that path. No branch renames involved.

Summary

Two related failures in ExitWorktree action="remove" when the session's working directory is inside the worktree being removed:

  1. (100% reproducible) Orphaned worktree despite a success message. The first remove is refused (Could not verify worktree state … Refusing to remove without explicit confirmation); after re-invoking with discard_changes: true it returns Exited and removed worktree at …, but the worktree directory, its .git/worktrees/<name>/ admin entry, and the worktree-<name> branch all remain. git worktree prune won't reap it (the dir is still present). This differs from EnterWorktree (name mode) writes core.hooksPath into the shared repo config; ExitWorktree doesn't restore it #67196's hypothesis that the leftover branch is caused by a mid-session git branch -m rename — here no rename is involved; a vanilla create → work → commit → push → exit cycle leaks.

  2. (Intermittent, severe) Parent-repo core.bare corruption. In one occurrence the same teardown left core.bare = true in the primary repo's shared .git/config. That breaks the whole repo: git status / git worktree / commit all fail with fatal: this operation must be run in a work tree, and git's "refusing to fetch into a checked-out branch" safety rail is disabled — so a later git fetch origin main:main advanced the ref while leaving the working tree frozen, surfacing in the next session as a phantom "staged revert" of everything that had changed since. It did not recur on clean single cycles; it appears tied to the messy refuse → retry path from symptom 1.

Steps to reproduce (the reliably-reproducible orphan)

  1. EnterWorktree (name mode) → session cwd becomes the worktree root.

  2. Without cd-ing out, call ExitWorktree { action: "remove" } → refused: Could not verify worktree state … Refusing to remove without explicit confirmation.

  3. ExitWorktree { action: "remove", discard_changes: true } → returns Exited and removed worktree at ….

  4. From the primary checkout, observe the leak:

    • git worktree list still lists the worktree
    • the worktree directory still exists on disk
    • git branch --list 'worktree-<name>' is still present
    • git worktree prune is a no-op (dir present)

    Cleanup requires a manual git worktree remove --force <path> + git branch -D worktree-<name>.

Observed 3× in one session — every time the session cwd was inside the worktree at removal.

What I verified about the core.bare variant

Plain git worktree remove --force <wt> and rm -rf <wt> && git worktree prune run from inside a worktree do not flip core.bare, so the mutation lives in ExitWorktree's own removal path, not in git. The WorktreeCreate hook does a plain git worktree add and never touches core.bare, and there is no custom remove hook.

Expected behavior

ExitWorktree action="remove" should either fully remove the worktree (directory + .git/worktrees/<name> admin entry + branch) or report failure — never (a) claim success while leaving the worktree registered, or (b) mutate the parent repo's core.bare (or any other shared .git/config key).

Workaround

  • cd to the primary checkout before calling ExitWorktree.
  • After teardown, verify with git worktree list and git config core.bare (must be false), and clean up any orphan manually.

Related issues

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:toolsbugSomething isn't workinghas reproHas detailed reproduction stepsplatform:macosIssue specifically occurs on macOS

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions