gastownhall/beads · error
worktree removal failure is absent or invalid
Error message
worktree removal failure is absent or invalid
What it means
ClassifyFailure exists to explain a removal error, so removeErr must be non-nil. If the caller invokes it after a removal that reported success (or with a nil error), there is nothing to classify and the function returns this error rather than fabricating an UnchangedFailure or PartialFailure result.
Source
Thrown at internal/worktreeremove/policy.go:335
const (
UnchangedFailure FailureKind = iota
PartialFailure
)
// Failure is the pure classification returned after a mutation error.
type Failure struct {
Kind FailureKind
RemoveErr error
}
// ClassifyFailure distinguishes a safely unchanged target from partial or
// indeterminate state. Presentation retains diagnostics at the command edge.
func ClassifyFailure(plan Plan, facts FailureFacts, removeErr error) (Failure, error) {
if !plan.valid() {
return Failure{}, fmt.Errorf("worktree removal approval is absent or invalid")
}
if removeErr == nil {
return Failure{}, fmt.Errorf("worktree removal failure is absent or invalid")
}
if facts.RevalidationResult == RevalidationPassed && facts.Registration == Present && facts.TargetPath == Present && revalidationValid(plan, facts.Revalidation) {
return Failure{Kind: UnchangedFailure, RemoveErr: removeErr}, nil
}
return Failure{Kind: PartialFailure, RemoveErr: removeErr}, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Only call ClassifyFailure when the removal function returned a non-nil error.
- On removal success, take the success path instead of invoking classification.
- If removal semantics changed, check err from Remove before deciding to classify.
Example fix
// before
classification, err := ClassifyFailure(plan, ffacts, removeErr)
// after
if removeErr != nil {
classification, err = ClassifyFailure(plan, ffacts, removeErr)
} else {
// removal succeeded — success path
} Defensive patterns
Strategy: validation
Validate before calling
if removeErr == nil {
// success path — do not call ClassifyFailure
return nil
}
classification, err := ClassifyFailure(plan, ffacts, removeErr) Prevention
- Call ClassifyFailure only inside the removal-error branch.
- Keep success and failure paths visibly separate in the removal flow.
- Avoid wrappers that classify unconditionally.
When it happens
Trigger: Calling ClassifyFailure with removeErr == nil, typically when the caller's control flow reaches failure classification unconditionally instead of only when RemoveWorktree returned an error.
Common situations: Copy-pasted error handling where the nil-error success branch is missing; wrapper code that logs/classifies regardless of removal outcome; refactoring that inverted an if condition around the remove call.
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/b1fc9d71f41bff34.
Report an issue: GitHub.