{"record":{"id":"61174816c86d698f","repo":"gastownhall/beads","slug":"target-is-no-longer-registered-at-s","errorCode":null,"errorMessage":"target is no longer registered at %s","messagePattern":"target is no longer registered at (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":1393,"sourceCode":"\t}\n\treturn filepath.ToSlash(relative), true\n}\n\ntype worktreeRevalidationObservation struct {\n\tfacts worktreeremove.RevalidationFacts\n\terr   error\n}\n\nfunc (plan *worktreeRemovalPlan) observeRevalidation(ctx context.Context) worktreeRevalidationObservation {\n\tfacts := worktreeremove.RevalidationFacts{}\n\tworktrees, err := listRegisteredWorktrees(ctx, plan.git, plan.executionRoot)\n\tif err != nil {\n\t\treturn worktreeRevalidationObservation{facts: facts, err: err}\n\t}\n\tcurrentEntry, found := findRegisteredWorktreeByPath(worktrees, plan.target.path)\n\tif !found {\n\t\tfacts.Registration = worktreeremove.InvariantChanged\n\t\treturn worktreeRevalidationObservation{facts: facts, err: fmt.Errorf(\"target is no longer registered at %s\", plan.target.path)}\n\t}\n\tif worktreeRegistryIdentity(currentEntry) != plan.target.registryID {\n\t\tfacts.Registration = worktreeremove.InvariantChanged\n\t\tif currentEntry.locked != plan.target.locked || currentEntry.lockReason != plan.target.lockReason ||\n\t\t\tcurrentEntry.prunable != plan.target.prunable || currentEntry.pruneReason != plan.target.pruneReason {\n\t\t\tfacts.LockPrune = worktreeremove.InvariantChanged\n\t\t}\n\t\treturn worktreeRevalidationObservation{facts: facts, err: fmt.Errorf(\"registered target identity changed\")}\n\t}\n\tfacts.Registration = worktreeremove.InvariantStable\n\tfacts.LockPrune = worktreeremove.InvariantStable\n\tfacts.TargetPath = worktreeremove.InvariantStable\n\n\tcurrentTarget, err := inspectWorktreeTarget(ctx, plan.git, currentEntry)\n\tif err != nil {\n\t\treturn worktreeRevalidationObservation{facts: facts, err: err}\n\t}\n\tif !sameWorktreePath(currentTarget.gitDir, plan.target.gitDir) {","sourceCodeStart":1375,"sourceCodeEnd":1411,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L1375-L1411","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: worktree deleted by another process between plan and execute\n$ bd worktree remove feature\n// error: target is no longer registered at /wt/feature\n// after\n$ git worktree list   # confirm gone, or re-add if needed\n$ bd worktree remove feature   # fresh plan, or skip if already removed","handlingStrategy":"retry","validationCode":"git worktree list --porcelain | grep -q \"^worktree /wt/feature$\" || { echo 'target already gone'; exit 0; }","typeGuard":"func worktreeRegisteredAt(path string, entries []worktreeEntry) bool {\n\tfor _, e := range entries {\n\t\tif e.path == path { return true }\n\t}\n\treturn false\n}","tryCatchPattern":"obs := revalidateWorktreePlan(ctx, plan)\nif errors.Is(obs.err, nil) { /* proceed */ }\nelse if strings.Contains(obs.err.Error(), \"no longer registered\") {\n\tplan, obs.err = rebuildPlan(ctx) // retry with a fresh plan\n}","preventionTips":["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"],"tags":["git","worktree","race-condition","stale-state"],"backgroundTag":"stale-worktree-state","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}