gastownhall/beads · error
target is no longer registered at %s
Error message
target is no longer registered at %s
What it means
Before executing a prepared removal, bd re-validates its plan against the live git state. This error means the worktree that was resolved as the removal target is no longer present in `git worktree list` at the recorded path — the world changed between planning and execution, so bd refuses to act on stale facts. It sets the Registration invariant to Changed and aborts revalidation.
Source
Thrown at cmd/bd/worktree_cmd.go:1393
}
return filepath.ToSlash(relative), true
}
type worktreeRevalidationObservation struct {
facts worktreeremove.RevalidationFacts
err error
}
func (plan *worktreeRemovalPlan) observeRevalidation(ctx context.Context) worktreeRevalidationObservation {
facts := worktreeremove.RevalidationFacts{}
worktrees, err := listRegisteredWorktrees(ctx, plan.git, plan.executionRoot)
if err != nil {
return worktreeRevalidationObservation{facts: facts, err: err}
}
currentEntry, found := findRegisteredWorktreeByPath(worktrees, plan.target.path)
if !found {
facts.Registration = worktreeremove.InvariantChanged
return worktreeRevalidationObservation{facts: facts, err: fmt.Errorf("target is no longer registered at %s", plan.target.path)}
}
if worktreeRegistryIdentity(currentEntry) != plan.target.registryID {
facts.Registration = worktreeremove.InvariantChanged
if currentEntry.locked != plan.target.locked || currentEntry.lockReason != plan.target.lockReason ||
currentEntry.prunable != plan.target.prunable || currentEntry.pruneReason != plan.target.pruneReason {
facts.LockPrune = worktreeremove.InvariantChanged
}
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) {View on GitHub (pinned to 71377f2769)
Solutions
- Re-run `bd worktree remove` from scratch so a fresh plan is built against current state
- Check `git worktree list` to confirm the target's current status; if it is already gone, nothing needs removing
- Coordinate with other processes/agents to avoid concurrent worktree removals on the same repo
Example fix
// before: worktree deleted by another process between plan and execute $ bd worktree remove feature // error: target is no longer registered at /wt/feature // after $ git worktree list # confirm gone, or re-add if needed $ bd worktree remove feature # fresh plan, or skip if already removed
Defensive patterns
Strategy: retry
Validate before calling
git worktree list --porcelain | grep -q "^worktree /wt/feature$" || { echo 'target already gone'; exit 0; } Type guard
func worktreeRegisteredAt(path string, entries []worktreeEntry) bool {
for _, e := range entries {
if e.path == path { return true }
}
return false
} Try / catch
obs := revalidateWorktreePlan(ctx, plan)
if errors.Is(obs.err, nil) { /* proceed */ }
else if strings.Contains(obs.err.Error(), "no longer registered") {
plan, obs.err = rebuildPlan(ctx) // retry with a fresh plan
} Prevention
- Don't run concurrent worktree removals/prunes on the same repo
- Serialize bd worktree operations when multiple agents share a repo
- Re-check `git worktree list` right before scripted removals
- Treat plan/execute as non-atomic: always be ready to rebuild the plan
When it happens
Trigger: Calling executeWorktreeRemoval (revalidation at cmd/bd/worktree_cmd.go:1393) after another process ran `git worktree remove`/`git worktree prune`, the directory's registration vanished, or git pruned a missing worktree between plan and execute.
Common situations: Another developer/agent or CI job removed the same worktree concurrently; a `git worktree prune` cleaned up a deleted directory; the target directory was deleted manually and git dropped it during an intervening git command.
Related errors
- target git directory changed
- target HEAD changed from %s to %s
- target cleanliness changed
- target HEAD disagrees with git worktree registry (registry %
- registered target identity changed
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/61174816c86d698f.
Report an issue: GitHub.