{"record":{"id":"a0111a13492ffab7","repo":"gastownhall/beads","slug":"comparison-ref-q-resolves-to-the-target-worktree","errorCode":null,"errorMessage":"comparison ref %q resolves to the target worktree branch and cannot independently prove containment","messagePattern":"comparison ref %q resolves to the target worktree branch and cannot independently prove containment","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":1881,"sourceCode":"\tgit *worktreeRemovalGit,\n\texecutionRoot string,\n\ttarget pinnedWorktreeTarget,\n\tselector string,\n\tref string,\n\texplicit bool,\n) (pinnedWorktreeComparator, error) {\n\tterminalRef, err := resolveWorktreeTerminalRef(ctx, git, executionRoot, ref)\n\tif err != nil {\n\t\treturn pinnedWorktreeComparator{}, err\n\t}\n\tif isWorktreeLocalRef(ref) || isWorktreeLocalRef(terminalRef) {\n\t\treturn pinnedWorktreeComparator{}, fmt.Errorf(\n\t\t\t\"comparison ref %q resolves through a worktree-local ref namespace and cannot independently prove containment\",\n\t\t\tref,\n\t\t)\n\t}\n\tif ref == target.branch || terminalRef == target.branch {\n\t\treturn pinnedWorktreeComparator{}, fmt.Errorf(\n\t\t\t\"comparison ref %q resolves to the target worktree branch and cannot independently prove containment\",\n\t\t\tref,\n\t\t)\n\t}\n\toid, err := resolveWorktreeCommitOID(ctx, git, executionRoot, ref)\n\tif err != nil {\n\t\treturn pinnedWorktreeComparator{}, fmt.Errorf(\"comparison ref %q does not resolve to a commit: %w\", ref, err)\n\t}\n\treturn pinnedWorktreeComparator{\n\t\tselector:    selector,\n\t\texplicit:    explicit,\n\t\tref:         ref,\n\t\tterminalRef: terminalRef,\n\t\toid:         oid,\n\t}, nil\n}\n\nfunc resolveWorktreeTerminalRef(","sourceCodeStart":1863,"sourceCodeEnd":1899,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L1863-L1899","documentation":"Even if a ref is valid and shared, if it names (or resolves to) the target worktree's own branch, it equals the HEAD being checked and cannot independently prove containment — an ancestor check of HEAD against itself is trivially self-referential — so bd rejects the selector.","triggerScenarios":"Passing `--merged-into <ref>` where `ref` equals `target.branch` or the ref's terminal resolution equals `target.branch`.","commonSituations":"Naming the branch checked out in the worktree being removed; a symbolic ref chain that ends at the target branch; scripting `--merged-into $(git symbolic-ref HEAD)` inside the target worktree.","solutions":["Pass the branch the worktree was merged INTO (e.g. `refs/heads/main`), not the worktree's own branch","Check the target branch name (shown by `bd worktree list`) and choose a different ref","Use a descendant commit OID on another branch that strictly contains the worktree HEAD"],"exampleFix":"// before (worktree's own branch)\nbd worktree remove --merged-into refs/heads/feature-x\n// after (the branch it was merged into)\nbd worktree remove --merged-into refs/heads/main","handlingStrategy":"validation","validationCode":"// shell pre-check: selector must not be the target branch\nbranch=$(git -C \"$WORKTREE\" symbolic-ref --short HEAD)\n[ \"$SEL\" != \"$branch\" ] || echo \"selector equals the target worktree branch\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose the merge-destination branch (main/develop), never the worktree's own branch","List worktrees and their branches (`bd worktree list`) before choosing a selector","Use a descendant commit on a different branch when in doubt"],"tags":["git","refs","self-reference","containment-proof"],"backgroundTag":"worktree-local-ref","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}