gastownhall/beads · error
ReclaimExpiredLeases: %w
Error message
ReclaimExpiredLeases: %w
What it means
ReclaimExpiredLeases wraps any error returned by the underlying issue repository's lease-reclaim operation. The use-case layer adds the 'ReclaimExpiredLeases:' prefix so callers can tell which storage operation failed while preserving the original driver/DB error via %w. It indicates lease reclaim (taking over expired leases on issues/wisps) could not be completed.
Source
Thrown at internal/storage/domain/issue.go:1937
// WakeExpiredDefers returns every expired DATED defer to open (see
// issueops.WakeExpiredDefersInTx) and reports how many permanent issues and
// wisps woke. The caller owns persistence: commit with a wake message iff
// issues > 0, and with the ephemeral plain-COMMIT form iff only wisps woke
// (wisp tables are dolt_ignored, so their wake needs a SQL commit but must
// mint no version commit).
func (u *issueUseCaseImpl) WakeExpiredDefers(ctx context.Context) (issues, wisps int, err error) {
issues, wisps, err = u.issueRepo.WakeExpiredDefers(ctx)
if err != nil {
return 0, 0, fmt.Errorf("WakeExpiredDefers: %w", err)
}
return issues, wisps, nil
}
func (u *issueUseCaseImpl) ReclaimExpiredLeases(ctx context.Context, olderThan time.Duration, filter types.ReclaimFilter, actor string) ([]types.ReclaimedLease, error) {
out, err := u.issueRepo.ReclaimExpiredLeases(ctx, olderThan, filter, actor)
if err != nil {
return nil, fmt.Errorf("ReclaimExpiredLeases: %w", err)
}
return out, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped error chain (errors.Unwrap / %v of the error) to find the underlying driver failure
- Verify the Dolt database is reachable and the server is up (bd dolt status / connection settings)
- Retry the reclaim after the storage layer recovers; the operation is safe to re-run
- If SQL/schema errors appear, run the beads migration/upgrade path to reconcile the schema
Example fix
// before
issues, err := uc.ReclaimExpiredLeases(ctx, ttl, filter, actor)
if err != nil {
return err // loses context
}
// after
if err != nil {
log.Printf("lease reclaim failed: %v", err) // log full wrapped chain
var recov bool
if errors.As(err, &driverErr) { recov = retryReclaim(ctx) }
return fmt.Errorf("reclaim: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
// check storage reachability before reclaim
if err := pingDolt(ctx); err != nil {
return fmt.Errorf("storage unavailable, skipping reclaim: %w", err)
} Try / catch
out, err := uc.ReclaimExpiredLeases(ctx, ttl, filter, actor)
if err != nil {
var wrapped error
if errors.As(err, &wrapped) { log.Printf("reclaim failed, driver says: %v", wrapped) }
return fmt.Errorf("reclaim: %w", err) // safe to retry later
} Prevention
- Run lease reclaim in a retry loop with backoff
- Monitor Dolt server health before scheduled sweeps
- Keep beads and its schema on matching versions
When it happens
Trigger: Calling issueUseCaseImpl.ReclaimExpiredLeases(ctx, olderThan, filter, actor) when the underlying issueRepo.ReclaimExpiredLeases query fails — e.g. Dolt/DB connection error, SQL error in the reclaim UPDATE/SELECT, or storage layer unavailable.
Common situations: Background lease-reclaim sweeps running while the Dolt database is restarting or unreachable; schema drift between beads versions causing SQL errors; concurrent write contention during a batch reclaim.
Related errors
- get molecule children: %w
- determining wisp status for %s: %w
- no store is open for this workspace
- not found
- db: ChildCounterSQLRepository.NextChildID: parentID must not
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9041bd0f097b596f.
Report an issue: GitHub.