gastownhall/beads · error
comparison ref %q resolves through a worktree-local ref name
Error message
comparison ref %q resolves through a worktree-local ref namespace and cannot independently prove containment
What it means
A `--merged-into` ref must independently prove containment of the worktree HEAD. If the provided ref, or the ref it resolves to (terminal ref), lives in a worktree-local ref namespace (e.g. `refs/worktree/...` or `refs/bd/worktrees/...` per `isWorktreeLocalRef`), it is not independent evidence, so bd rejects it.
Source
Thrown at cmd/bd/worktree_cmd.go:1875
}
return true
}
func pinWorktreeComparatorRef(
ctx context.Context,
git *worktreeRemovalGit,
executionRoot string,
target pinnedWorktreeTarget,
selector string,
ref string,
explicit bool,
) (pinnedWorktreeComparator, error) {
terminalRef, err := resolveWorktreeTerminalRef(ctx, git, executionRoot, ref)
if err != nil {
return pinnedWorktreeComparator{}, err
}
if isWorktreeLocalRef(ref) || isWorktreeLocalRef(terminalRef) {
return pinnedWorktreeComparator{}, fmt.Errorf(
"comparison ref %q resolves through a worktree-local ref namespace and cannot independently prove containment",
ref,
)
}
if ref == target.branch || terminalRef == target.branch {
return pinnedWorktreeComparator{}, fmt.Errorf(
"comparison ref %q resolves to the target worktree branch and cannot independently prove containment",
ref,
)
}
oid, err := resolveWorktreeCommitOID(ctx, git, executionRoot, ref)
if err != nil {
return pinnedWorktreeComparator{}, fmt.Errorf("comparison ref %q does not resolve to a commit: %w", ref, err)
}
return pinnedWorktreeComparator{
selector: selector,
explicit: explicit,
ref: ref,View on GitHub (pinned to 71377f2769)
Solutions
- Use a shared repository ref such as `refs/heads/<branch>` or a remote-tracking ref like `origin/main`
- Inspect what the selector resolves to with `git rev-parse --symbolic-full-name <ref>` and pick a non-worktree-local equivalent
- Pass the full commit OID of the merged-into commit instead of the worktree-local ref
Example fix
// before bd worktree remove --merged-into refs/worktree/wt-7/main // after bd worktree remove --merged-into refs/heads/main
Defensive patterns
Strategy: validation
Validate before calling
// shell pre-check: reject worktree-local namespaces full=$(git rev-parse --symbolic-full-name "$REF" 2>/dev/null || true) case "$full" in refs/worktree/*|refs/bd/*) echo "$full is worktree-local" ;; esac
Prevention
- Only pass refs/heads/* or refs/remotes/* refs to --merged-into
- Avoid scripting against bd-internal worktree ref namespaces
- Resolve the terminal ref with `git rev-parse --symbolic-full-name` before passing it
When it happens
Trigger: Passing a ref whose name, or whose resolved terminal ref name, is inside a worktree-local namespace to `--merged-into`.
Common situations: Using bd-internal per-worktree refs generated by worktree management; copying a refname like `refs/worktree/<id>/HEAD` from bd output; scripting against internal namespaces.
Related errors
- comparison ref %q resolves to the target worktree branch and
- --merged-into object ID %q is the target HEAD itself; use a
- not a git repository
- failed to install hooks: %w
- git config --unset core.hooksPath failed: %w (output: %s)
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e99783824ac34653.
Report an issue: GitHub.