gastownhall/beads · error
reading custom statuses for wisp age GC: %w
Error message
reading custom statuses for wisp age GC: %w
What it means
During wisp age-based garbage collection, protectedWispStatuses builds the set of statuses that must not be collected, including custom statuses categorized as WIP or Frozen. If reading the custom status definitions from the repository fails, the GC cannot know what is protected and aborts with this wrapped error rather than risk deleting wisps it should preserve.
Source
Thrown at cmd/bd/wisp.go:688
protected := make(map[types.Status]bool)
for _, s := range []types.Status{
types.StatusOpen,
types.StatusInProgress,
types.StatusBlocked,
types.StatusClosed,
types.StatusDeferred,
types.StatusPinned,
types.StatusHooked,
} {
switch types.BuiltInStatusCategory(s) {
case types.CategoryWIP, types.CategoryFrozen:
protected[s] = true
}
}
customStatuses, err := r.GetCustomStatusesDetailed(ctx)
if err != nil {
return nil, fmt.Errorf("reading custom statuses for wisp age GC: %w", err)
}
for _, cs := range customStatuses {
switch cs.Category {
case types.CategoryWIP, types.CategoryFrozen:
protected[types.Status(cs.Name)] = true
}
}
return protected, nil
}
// isProtectedWisp reports whether a wisp is live work that age-based GC must
// never reclaim. A wisp is protected if it is explicitly pinned, if it is
// blocked on an open dependency (blockedSet, derived from is_blocked), or if
// its status falls in a protected category. Reclaiming any of these
// mid-execution destroys active molecules (GH#4394).
//
// Named isProtectedWisp rather than isActiveWisp to avoid confusion with
// (*DoltStore).isActiveWisp in internal/storage/dolt, which is in this sameView on GitHub (pinned to 71377f2769)
Solutions
- Check database connectivity and retry the GC command
- Inspect/repair custom status configuration (`bd statuses` or equivalent)
- Investigate the wrapped inner error (%w) for the root cause
Defensive patterns
Strategy: retry
Validate before calling
if err := pingStore(ctx, r); err != nil {
return fmt.Errorf("store unreachable; defer wisp GC: %w", err)
} Try / catch
if err := runWispGC(ctx); err != nil {
var wrapped string = err.Error()
if strings.Contains(wrapped, "reading custom statuses for wisp age GC") {
// retry with backoff or skip GC this cycle; never GC without the protected set
}
} Prevention
- Run GC only when the database is healthy/reachable
- Always load the protected-status set before any deletion pass
- Treat custom-status read failures as fatal to GC, never as empty
When it happens
Trigger: findAbandonedWisps calls r.GetCustomStatusesDetailed(ctx) and the underlying store/driver returns an error (database unavailable, corrupted status config, driver failure).
Common situations: Database locked or unreachable during GC runs in CI; Dolt/storage driver failures; corrupted custom-status configuration in .beads metadata.
Related errors
- determining blocked wisps for age GC: %w
- affected by batched wisp delete: %w
- LoadCreateContext: read custom statuses: %w
- no store is open for this workspace
- not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f8f81e89310d870b.
Report an issue: GitHub.