gastownhall/beads · error

registered target identity changed (git marker mismatch)

Error message

registered target identity changed (git marker mismatch)

What it means

Raised during `bd worktree remove` revalidation: the fingerprint of the worktree's git marker (`.git` pointer file) content differs from the one captured when the removal plan was built. Even though the file itself is the same inode, its contents were rewritten (e.g. now pointing at a different admin directory or a different gitdir path). bd aborts because the registered worktree it plans to remove now references different git internals than were verified.

Source

Thrown at cmd/bd/worktree_cmd.go:1471

		!samePinnedFileMetadata(currentTarget.gitDirInfo, plan.target.gitDirInfo) {
		facts.GitAdminDirectory = worktreeremove.InvariantChanged
		return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target git directory identity changed")}
	}
	facts.GitAdminDirectory = worktreeremove.InvariantStable
	if !os.SameFile(currentTarget.gitMarkerInfo, plan.target.gitMarkerInfo) ||
		!samePinnedFileMetadata(currentTarget.gitMarkerInfo, plan.target.gitMarkerInfo) {
		facts.GitMarker = worktreeremove.InvariantChanged
		return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target git marker identity changed")}
	}
	facts.GitMarker = worktreeremove.InvariantStable
	if currentTarget.gitDirFingerprint != plan.target.gitDirFingerprint {
		facts.GitAdminDirectoryBytes = worktreeremove.InvariantChanged
		return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target git directory identity changed (contents mismatch)")}
	}
	facts.GitAdminDirectoryBytes = worktreeremove.InvariantStable
	if currentTarget.gitMarkerFingerprint != plan.target.gitMarkerFingerprint {
		facts.GitMarkerBytes = worktreeremove.InvariantChanged
		return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("registered target identity changed (git marker mismatch)")}
	}
	facts.GitMarkerBytes = worktreeremove.InvariantStable
	if plan.gitignoreCleanup != nil {
		if err := plan.gitignoreCleanup.validate(); err != nil {
			facts.ManagedIgnore = worktreeremove.InvariantChanged
			return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf(".gitignore changed before removal: %w", err)}
		}
	}
	facts.ManagedIgnore = worktreeremove.InvariantStable

	if plan.comparator == nil {
		facts.Comparator = worktreeremove.InvariantNotRequired
		facts.Containment = worktreeremove.InvariantNotRequired
		return worktreeRevalidationObservation{facts: facts}
	}
	currentComparator, err := plan.resolveComparator(ctx, currentTarget)
	if err != nil {
		return worktreeRevalidationObservation{facts: facts, err: err}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-run `bd worktree remove` to rebuild the plan against the marker's current contents
  2. Find what rewrote the marker (`git worktree list`, `git worktree repair --dry-run`) and complete that operation first, then remove
  3. Verify the marker now points at the expected admin directory (`cat <worktree>/.git`); if it points elsewhere, the old plan is unsafe — discard it
  4. If the worktree was intentionally re-pointed, remove it with a fresh command rather than forcing the stale plan

Example fix

// before: marker re-pointed by `git worktree move` after planning
plan := buildRemovalPlan(target)
gitWorktreeMove(mainRepo)
executeRemoval(plan) // fails: git marker mismatch
// after: move first, then plan and remove
repoPath := gitWorktreeMove(mainRepo)
plan := buildRemovalPlan(targetAt(repoPath))
executeRemoval(plan)
Defensive patterns

Strategy: validation

Validate before calling

// Compare the marker's current content with what was planned against:
marker := filepath.Join(worktreePath, ".git")
cur, err := os.ReadFile(marker)
if err != nil { return err }
if string(cur) != pinned.gitMarkerContent {
    return fmt.Errorf("marker re-pointed to %q; rebuild plan", string(cur))
}

Try / catch

err := bdWorktreeRemove(path)
if err != nil && strings.Contains(err.Error(), "git marker mismatch") {
    // marker contents rewritten: verify new target, then retry
    verifyMarkerTarget(path)
    err = rebuildPlanAndRemove(path)
}

Prevention

When it happens

Trigger: Calling `bd worktree remove` after the `.git` marker's text was rewritten between plan and execution: `git worktree repair` or `git worktree move` re-pointed it, a manual edit of the `.git` file, re-initialization of the worktree, or a tool normalizing/rewriting gitdir paths.

Common situations: Running `git worktree move` on the main repo (changing relative gitdir paths inside markers); a script that regenerates worktrees in place; repository relocation or mount-path changes causing git to rewrite markers; manual edits while debugging.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/b73be430e08dc3ab. Report an issue: GitHub.