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

  1. Use a shared repository ref such as `refs/heads/<branch>` or a remote-tracking ref like `origin/main`
  2. Inspect what the selector resolves to with `git rev-parse --symbolic-full-name <ref>` and pick a non-worktree-local equivalent
  3. 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

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


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