{"record":{"id":"840089b5cfbf8f4d","repo":"gastownhall/beads","slug":"comparison-ref-q-does-not-resolve-to-a-commit-w","errorCode":null,"errorMessage":"comparison ref %q does not resolve to a commit: %w","messagePattern":"comparison ref %q does not resolve to a commit: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":1888,"sourceCode":"\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(\n\tctx context.Context,\n\tgit *worktreeRemovalGit,\n\texecutionRoot string,\n\tref string,\n) (string, error) {\n\tcurrent := ref\n\tseen := make(map[string]struct{})","sourceCodeStart":1870,"sourceCodeEnd":1906,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L1870-L1906","documentation":"For an accepted comparison ref, bd resolves it to a commit OID via `resolveWorktreeCommitOID`. If resolution fails (unknown ref, non-commit object, git error), this wrapped error reports the ref name plus the underlying cause.","triggerScenarios":"`--merged-into <ref>` where the ref exists as a name pattern but `git rev-parse <ref>^{commit}` fails — dangling symbolic ref, ref pointing to a tree/blob/tag that cannot peel to a commit, or ref deleted between validation and resolution.","commonSituations":"Remote-tracking ref whose remote was pruned; annotated tag resolving unexpectedly in a shallow clone; race where the branch is deleted while the command runs; broken symref (`refs/heads/x` → deleted branch).","solutions":["Run `git rev-parse <ref>^{commit}` to reproduce the underlying error","Verify the ref exists with `git show-ref | grep <ref>` and re-fetch if it is a remote ref (`git fetch origin`)","Use a concrete local branch (`refs/heads/...`) or a full commit OID instead","Check for broken symbolic refs with `git symbolic-ref <ref>` and repair"],"exampleFix":"// diagnose\ngit rev-parse origin/feature-x^{commit}\n// fix stale remote ref\ngit fetch origin --prune\nbd worktree remove --merged-into refs/heads/main","handlingStrategy":"validation","validationCode":"// shell pre-check\ngit rev-parse \"$REF^{commit}\" >/dev/null 2>&1 || echo \"$REF does not resolve to a commit\"","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"does not resolve to a commit\") {\n    // refresh refs (git fetch --prune) or switch to a full commit OID, then retry\n}","preventionTips":["Run `git fetch --prune` so remote-tracking refs are fresh","Validate with `git rev-parse <ref>^{commit}` before invoking bd","Prefer local branches or full OIDs over remote-tracking refs in scripts"],"tags":["git","ref-resolution","oid","cli"],"backgroundTag":"invalid-git-object-id","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}