gastownhall/beads · error
cannot verify unpushed commits: no comparison target is avai
Error message
cannot verify unpushed commits: no comparison target is available
What it means
Prepare rejects the request because mode is Normal and facts.Comparator is ComparatorMissing or ComparatorNotRequired — no comparison target (e.g. upstream branch) exists to prove the worktree HEAD was pushed. Removing could orphan commits, so the library fails closed.
Source
Thrown at internal/worktreeremove/policy.go:208
}
if facts.Status != Clean && facts.Status != Dirty {
return Plan{}, fmt.Errorf("worktree cleanliness observation is absent or invalid")
}
if facts.ManagedIgnore != IgnoreAbsent && facts.ManagedIgnore != IgnoreManaged {
return Plan{}, fmt.Errorf("managed ignore observation is absent or invalid")
}
if (facts.ManagedIgnore == IgnoreManaged) != (facts.ManagedIgnoreEntry != "") {
return Plan{}, fmt.Errorf("managed ignore cleanup identity is absent or invalid")
}
if request.Mode != Force {
if facts.Status != Clean {
return Plan{}, fmt.Errorf("worktree contains modified, untracked, or ignored files")
}
if facts.Comparator != ComparatorAvailable && facts.Comparator != ComparatorMissing && facts.Comparator != ComparatorNotRequired {
return Plan{}, fmt.Errorf("worktree comparison target observation is absent or invalid")
}
if facts.Comparator != ComparatorAvailable {
return Plan{}, fmt.Errorf("cannot verify unpushed commits: no comparison target is available")
}
if facts.Containment != Contained && facts.Containment != NotContained && facts.Containment != ContainmentNotRequired {
return Plan{}, fmt.Errorf("worktree containment observation is absent or invalid")
}
if facts.Containment != Contained {
return Plan{}, fmt.Errorf("worktree HEAD is not contained in the comparison target")
}
} else if facts.Comparator != ComparatorNotRequired || facts.Containment != ContainmentNotRequired {
return Plan{}, fmt.Errorf("worktree force-mode comparison observations are inconsistent")
}
plan := Plan{approved: true, mode: request.Mode, targetPath: facts.RegisteredPath}
if facts.ManagedIgnore == IgnoreManaged {
plan.managedIgnoreEntry = facts.ManagedIgnoreEntry
}
return plan, nil
}
// InvariantState is the adapter's raw observation of one independentlyView on GitHub (pinned to 71377f2769)
Solutions
- Push the worktree branch to a remote (git push -u origin <branch>) so a comparison target exists
- Push the worktree HEAD to a ref the comparator resolves, then retry
- Use Force mode only if losing the commits is acceptable
Example fix
// before plan, err := worktreeremove.Prepare(req, facts) // Normal mode, Comparator == ComparatorMissing // after // git push -u origin <branch> in the worktree, re-observe facts, then: plan, err := worktreeremove.Prepare(req, facts)
Defensive patterns
Strategy: validation
Validate before calling
if facts.Comparator != worktreeremove.ComparatorAvailable {
return fmt.Errorf("no upstream ref for %s; push or use Force", facts.RegisteredPath)
} Type guard
func hasComparisonTarget(c worktreeremove.ComparatorKind) bool {
return c == worktreeremove.ComparatorAvailable
} Try / catch
plan, err := worktreeremove.Prepare(req, facts)
if err != nil && strings.Contains(err.Error(), "no comparison target is available") {
return fmt.Errorf("push the branch (git push -u origin <branch>) or use Force: %w", err)
} Prevention
- Push worktree branches before removal workflows
- Configure upstream tracking on new branches
- Automate push-before-clean in CI scripts
When it happens
Trigger: Calling Prepare with Mode: Normal while the worktree branch has no upstream / comparison ref (Comparator != ComparatorAvailable).
Common situations: A local-only branch that was never pushed; the remote branch was deleted; upstream not configured after cloning a single branch.
Related errors
- worktree HEAD is not contained in the comparison target
- 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
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/51aa4d05f15f4d91.
Report an issue: GitHub.