{"record":{"id":"ee96a29386436e9c","repo":"gastownhall/beads","slug":"scanning-open-beads-for-references-w-ee96a2","errorCode":null,"errorMessage":"scanning open beads for references: %w","messagePattern":"scanning open beads for references: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/uow/sweeper.go","lineNumber":139,"sourceCode":"// candidates came off. Comments are read for the whole not-done set in ONE\n// batch rather than one query per row.\nfunc sweepReferencedInUOW(ctx context.Context, uw UnitOfWork, candidates []*types.Issue) (map[string]bool, error) {\n\tif len(candidates) == 0 {\n\t\treturn nil, nil\n\t}\n\tcandidateIDs := make(map[string]bool, len(candidates))\n\tfor _, issue := range candidates {\n\t\tcandidateIDs[issue.ID] = true\n\t}\n\tmatcher := workapi.NewCandidateIDMatcher(candidateIDs)\n\n\tcustom, err := uw.ConfigUseCase().GetCustomStatuses(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading custom statuses for reference scan: %w\", err)\n\t}\n\tpage, err := uw.IssueUseCase().SearchIssues(ctx, \"\", workapi.BuildSweepReferenceScanFilter(custom))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"scanning open beads for references: %w\", err)\n\t}\n\tnotDone := page.Items\n\n\tnotDoneIDs := make([]string, 0, len(notDone))\n\tfor _, issue := range notDone {\n\t\tif issue != nil {\n\t\t\tnotDoneIDs = append(notDoneIDs, issue.ID)\n\t\t}\n\t}\n\t// BOTH PLANES, and this is not an optimization detail. The not-done set\n\t// comes from SearchIssues, which merges the durable and wisp planes, so it\n\t// contains wisps — and their comments live in wisp_comments, which\n\t// GetCommentsForIssues does not read. Scanning only the durable table left\n\t// a closed bead cited solely by a comment on an open WISP unprotected, so\n\t// `bd prune` deleted it on this route and kept it on the other. The\n\t// contract says an implementation that cannot read the full set must fail\n\t// the sweep rather than under-scan it.\n\t//","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/sweeper.go#L121-L157","documentation":"This wraps a failure from IssueUseCase().SearchIssues when the sweeper scans all open (not-done) beads to look for references to candidate issues. The sweep contract says an implementation that cannot read the full not-done set must fail rather than under-scan, so any search error aborts the sweep with this message instead of proceeding and potentially deleting still-referenced beads.","triggerScenarios":"bd prune/sweep runs and SearchIssues with the sweep reference scan filter (built from custom statuses) fails — SQL error on the issues/wisps tables, connection loss mid-UOW, or a malformed filter due to unusual custom status values.","commonSituations":"Dolt server unavailable or timing out on large repos; schema drift between beads versions in the issues table; a corrupted database file after an unclean shutdown.","solutions":["Read the wrapped cause for the real SearchIssues error and address it (connectivity, schema, corruption)","Retry the sweep after restoring the database connection; the sweep is safe to re-run","Run a consistency check/repair on the Dolt database if the error persists","Update beads so the issues/wisps schema matches the binary's expectations"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: confirm the issues table is queryable before sweeping\nrows, err := db.QueryContext(ctx, \"SELECT 1 FROM issues LIMIT 1\")\nif err != nil {\n    return fmt.Errorf(\"issues table not readable, skip sweep: %w\", err)\n}\nrows.Close()","typeGuard":null,"tryCatchPattern":"result, err := sweeper.Sweep(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"scanning open beads for references\") {\n    // sweep is idempotent: back off and retry once the DB is healthy\n    return retrySweepWithBackoff(ctx, req)\n}","preventionTips":["Run sweeps when the database connection is stable; avoid sweeping during server maintenance","Raise query timeouts for large repositories","Re-run bd migrations after any version change","Repair the database promptly if corruption errors appear"],"tags":["storage","query","sweep"],"backgroundTag":"database-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}