gastownhall/beads · error
target common git directory changed
Error message
target common git directory changed
What it means
Revalidation also compares the target's common git directory with the plan's recorded commonDir. A mismatch means the worktree now shares metadata with a different repository (or the repo's common dir moved), so executing the prepared plan could damage the wrong repository. bd aborts, marking CommonDirectory as Changed, and reports this error.
Source
Thrown at cmd/bd/worktree_cmd.go:1418
}
return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("registered target identity changed")}
}
facts.Registration = worktreeremove.InvariantStable
facts.LockPrune = worktreeremove.InvariantStable
facts.TargetPath = worktreeremove.InvariantStable
currentTarget, err := inspectWorktreeTarget(ctx, plan.git, currentEntry)
if err != nil {
return worktreeRevalidationObservation{facts: facts, err: err}
}
if !sameWorktreePath(currentTarget.gitDir, plan.target.gitDir) {
facts.GitAdminDirectory = worktreeremove.InvariantChanged
return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target git directory changed")}
}
facts.GitAdminDirectory = worktreeremove.InvariantStable
if !sameWorktreePath(currentTarget.commonDir, plan.commonDir) {
facts.CommonDirectory = worktreeremove.InvariantChanged
return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target common git directory changed")}
}
facts.CommonDirectory = worktreeremove.InvariantStable
if currentTarget.headOID != plan.target.headOID {
facts.Head = worktreeremove.InvariantChanged
return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target HEAD changed from %s to %s", plan.target.headOID, currentTarget.headOID)}
}
facts.Head = worktreeremove.InvariantStable
if currentTarget.status != plan.target.status {
if (currentTarget.status == "") != (plan.target.status == "") {
facts.Cleanliness = worktreeremove.InvariantChanged
} else {
facts.Cleanliness = worktreeremove.InvariantStable
}
facts.StatusBytes = worktreeremove.InvariantChanged
return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target cleanliness changed")}
}
facts.Cleanliness = worktreeremove.InvariantStable
facts.StatusBytes = worktreeremove.InvariantStableView on GitHub (pinned to 71377f2769)
Solutions
- Rebuild by re-running `bd worktree remove` so the plan captures the current common dir
- Verify the main repo path hasn't moved; update the worktree with `git worktree repair` from the primary repo if it has
- Serialize operations: don't move/re-clone the repository while a worktree removal is pending
Example fix
// before: repo moved after plan was built $ bd worktree remove feature // error: target common git directory changed // after $ cd /new/location/repo && git worktree repair $ bd worktree remove feature # fresh plan
Defensive patterns
Strategy: retry
Validate before calling
cur=$(git -C /wt/feature rev-parse --path-format=absolute --git-common-dir)
[ "$cur" = "$RECORDED_COMMON_DIR" ] || { echo 'repo common dir moved; rebuild plan'; exit 1; } Type guard
func commonDirStable(before, after string) bool {
return filepath.Clean(before) == filepath.Clean(after)
} Try / catch
obs := revalidateWorktreePlan(ctx, plan)
if obs.err != nil && strings.Contains(obs.err.Error(), "common git directory changed") {
return fmt.Errorf("repository structure changed; re-run bd worktree remove from the primary repo")
} Prevention
- Don't move or re-clone the primary repo while worktree operations are pending
- Run `git worktree repair` from the primary repo after any repo relocation
- Keep the primary repo at a stable absolute path (avoid renameable mount points)
- Always execute removal promptly after planning; never persist plans across repo restructures
When it happens
Trigger: Executing a removal plan after the repository's common dir changed (repo moved/cloned, .git structure rearranged, worktree re-linked to another clone) between plan build and execution.
Common situations: The main repo was moved or its path changed (macOS /Volumes mounts, renamed directories) after the plan was built; the worktree was re-added against a different clone; `git worktree repair` relinked to a different primary.
Related errors
- target HEAD disagrees with git worktree registry (registry %
- target common git directory %q does not match repository %q
- target is no longer registered at %s
- registered target identity changed
- target git directory changed
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4dd21fae62fd0bce.
Report an issue: GitHub.