{"record":{"id":"225a59673e49cc63","repo":"gastownhall/beads","slug":"listing-sweep-candidates-w-225a59","errorCode":null,"errorMessage":"listing sweep candidates: %w","messagePattern":"listing sweep candidates: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/uow/sweeper.go","lineNumber":81,"sourceCode":"\treturn RunTxResult(ctx, s.provider, func(ctx context.Context, uw UnitOfWork) (publicops.SweepResult, string, error) {\n\t\tresult, err := sweepInUOW(ctx, uw, req)\n\t\tif err != nil || result.Swept == 0 {\n\t\t\t// A sweep that deleted nothing labels nothing: the role promises\n\t\t\t// at most one history entry per call and none for a no-op.\n\t\t\treturn result, \"\", err\n\t\t}\n\t\treturn result, fmt.Sprintf(\"bd: sweep %d %s bead(s)\", result.Swept, req.Tier), nil\n\t})\n}\n\n// sweepInUOW is the whole sweep on one unit of work, shared by the preview\n// path and the committing one so the two cannot answer differently.\nfunc sweepInUOW(ctx context.Context, uw UnitOfWork, req publicops.SweepRequest) (publicops.SweepResult, error) {\n\tresult := publicops.SweepResult{DryRun: req.DryRun}\n\n\tpage, err := uw.IssueUseCase().SearchIssues(ctx, \"\", workapi.BuildSweepCandidateFilter(req))\n\tif err != nil {\n\t\treturn publicops.SweepResult{}, fmt.Errorf(\"listing sweep candidates: %w\", err)\n\t}\n\n\tkept, skips := workapi.FilterSweepCandidates(page.Items, req.IDPattern, req.ClosedBefore)\n\tresult.Skipped = skips\n\n\tif req.ProtectReferenced {\n\t\treferenced, err := sweepReferencedInUOW(ctx, uw, kept)\n\t\tif err != nil {\n\t\t\treturn publicops.SweepResult{}, err\n\t\t}\n\t\tvar count int\n\t\tkept, count, result.ReferencedIDs = workapi.PartitionSweepReferenced(kept, referenced)\n\t\tresult.Skipped.Referenced = count\n\t}\n\n\tif len(kept) == 0 {\n\t\treturn result, nil\n\t}","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/sweeper.go#L63-L99","documentation":"sweepInUOW lists sweep candidates by calling IssueUseCase().SearchIssues with a sweep-candidate filter and wraps any failure with 'listing sweep candidates'. The sweep cannot proceed without the candidate page, so this error aborts the whole sweep operation.","triggerScenarios":"Running a sweep (publicops SweepRequest) where SearchIssues(ctx, \"\", BuildSweepCandidateFilter(req)) errors — SQL failure, malformed filter, connection loss, or use-case error while paging candidates.","commonSituations":"'bd sweep' run against an unhealthy or unreachable Dolt server; an ID pattern / closed-before filter combination producing a bad query; concurrent migration changing schema mid-sweep; ctx timeout on a large database where the candidate scan is slow.","solutions":["Retry the sweep; check the underlying error wrapped by %w for the SQL cause","Verify database connectivity and server health","Sweep in smaller batches (tighter --closed-before window) to reduce scan size","Verify the database schema is current (run any bd write command to migrate on non-bts setups)"],"exampleFix":"// before\nbd sweep --dry-run --closed-before 2020-01-01  # listing sweep candidates: timeout\n// after\nbd sweep --dry-run --closed-before 2024-01-01  # narrower window, smaller scan","handlingStrategy":"retry","validationCode":"-- preflight: ensure schema current and the sweep query is cheap\nSELECT COUNT(*) FROM issues WHERE status = 'closed' AND ...  -- estimate candidate size before sweeping","typeGuard":"func isSweepListingError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"listing sweep candidates: \")\n}","tryCatchPattern":"res, err := Sweep(ctx, req)\nif isSweepListingError(err) {\n  // transient or too-broad filter: narrow window and retry once\n  req.ClosedBefore = narrowWindow(req.ClosedBefore)\n  time.Sleep(time.Second); res, err = Sweep(ctx, req)\n}\nreturn res, err","preventionTips":["Keep the database schema current before sweeping","Use --dry-run and tighter --closed-before windows to bound scan size","Run sweeps during low-contention periods","Retry transient wrapped errors with backoff before escalating"],"tags":["database","query-error","sweep","maintenance"],"backgroundTag":"candidate-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}