gastownhall/beads · error
cannot verify unpushed commits: target is detached; use --me
Error message
cannot verify unpushed commits: target is detached; use --merged-into <ref>
What it means
This error is returned when the pinned-worktree verification needs to determine which commits on a worktree's branch are unpushed, but the target worktree is in a detached-HEAD state (or has no branch name). Without a branch there is no upstream or merge-base to compare against, so the library refuses to guess and asks the caller to supply an explicit reference via --merged-into <ref>.
Source
Thrown at cmd/bd/worktree_cmd.go:1967
oid := strings.TrimSpace(string(output))
hashLength, err := repositoryObjectIDLength(ctx, git, executionRoot)
if err != nil {
return "", err
}
if !isHexObjectID(oid, hashLength) {
return "", fmt.Errorf("git returned invalid commit object ID %q", oid)
}
return strings.ToLower(oid), nil
}
func resolveUpstreamWorktreeComparator(
ctx context.Context,
git *worktreeRemovalGit,
executionRoot string,
target pinnedWorktreeTarget,
) (pinnedWorktreeComparator, error) {
if target.branch == "" || target.detached {
return pinnedWorktreeComparator{}, fmt.Errorf(
"cannot verify unpushed commits: target is detached; use --merged-into <ref>",
)
}
output, err := git.output(
ctx,
executionRoot,
"for-each-ref",
"--format=%(upstream)",
"--",
target.branch,
)
if err != nil {
return pinnedWorktreeComparator{}, fmt.Errorf("failed to inspect configured upstream: %w", err)
}
upstreamRef := strings.TrimSpace(string(output))
if upstreamRef == "" || strings.Contains(upstreamRef, "\n") {
return pinnedWorktreeComparator{}, fmt.Errorf(
"cannot verify unpushed commits: the target branch has no single resolvable upstream; configure an upstream or use --merged-into <ref>",View on GitHub (pinned to 71377f2769)
Solutions
- Pass --merged-into <ref> to give the verifier an explicit reference to compare against (e.g. the base branch like main).
- Re-attach the worktree to a branch: from inside the worktree run `git switch -c <branch>` (or `git switch <existing-branch>`).
- If the detached state is unintended, recreate the worktree with `git worktree add <path> <branch>` instead of a SHA.
Example fix
// before bd worktree remove mytask # worktree is detached; verification fails // after bd worktree remove mytask --merged-into main
Defensive patterns
Strategy: validation
Validate before calling
branch := execGit("git", "rev-parse", "--abbrev-ref", "HEAD")
if branch == "HEAD" || branch == "" {
// detached: supply --merged-into explicitly
args = append(args, "--merged-into", "main")
} Prevention
- Always create worktrees bound to a branch (`git worktree add <path> <branch>`), never a raw SHA.
- Before running worktree verification, check `git symbolic-ref -q HEAD` for emptiness (detached).
- In CI, prefer `actions/checkout` with ref=<branch> over SHA checkouts when worktree tooling will run.
- Adopt the habit of passing --merged-into explicitly in scripts so detached states never break them.
When it happens
Trigger: Calling the pinned-worktree comparison flow (newPinnedWorktreeComparator path in cmd/bd/worktree_cmd.go) when target.branch is empty or target.detached is true — i.e. the worktree was created with a detached HEAD (e.g. `git worktree add --detach`, checking out a raw commit SHA, or a rebase/checkout left HEAD detached).
Common situations: CI pipelines that check out commits by SHA into worktrees; a user who ran `git checkout <sha>` inside a linked worktree; worktrees created by tooling that pins an exact revision; a branch that was deleted leaving the worktree detached.
Related errors
- failed to inspect created worktree cleanliness: %w %s
- created worktree is dirty after checkout; refusing to contin
- worktree not found: %s
- failed to read git worktree registry: %w
- git worktree registry is empty
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3c3615538adda321.
Report an issue: GitHub.