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

  1. Pass --merged-into <ref> to give the verifier an explicit reference to compare against (e.g. the base branch like main).
  2. Re-attach the worktree to a branch: from inside the worktree run `git switch -c <branch>` (or `git switch <existing-branch>`).
  3. 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

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


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