{"record":{"id":"ab362e6469379ad3","repo":"gastownhall/beads","slug":"reading-custom-statuses-for-reference-scan-w-ab362e","errorCode":null,"errorMessage":"reading custom statuses for reference scan: %w","messagePattern":"reading custom statuses for reference scan: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/uow/sweeper.go","lineNumber":135,"sourceCode":"}\n\n// sweepReferencedInUOW returns which of the candidates a not-done row cites,\n// reading the not-done set and its comments on the same unit of work the\n// 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","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/sweeper.go#L117-L153","documentation":"This error wraps any failure from GetCustomStatuses while the sweep's reference scan is preparing its filter inside a unit of work. The scan must know which statuses count as 'done' (including user-defined custom statuses) before searching open beads, so a config read failure aborts the whole sweep rather than guessing. The library throws it to preserve the underlying config/storage error while marking the sweep stage that failed.","triggerScenarios":"Calling bd prune/sweep when the underlying config store (dolt `config` tables) is unreadable — e.g. database connection dropped mid-unit-of-work, corrupt or missing config table, or the ConfigUseCase's query fails for a permissions/schema reason.","commonSituations":"A Dolt server restart or network blip between opening the UOW and reading config; running against a repo whose .beads database was created by an older version lacking the custom-status schema; file-permission problems on the embedded database.","solutions":["Inspect the wrapped cause (%w) for the actual config/storage failure and fix that first","Re-open the database / retry the sweep once connectivity to the Dolt backend is restored","Verify the .beads database schema is current (run bd's migration/doctor command) and that no older beads version downgraded it","Check filesystem permissions on the database files if using embedded mode"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Go: check the config store is reachable before sweeping\nif err := db.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"database unreachable before sweep: %w\", err)\n}","typeGuard":"if custom, err := cfgUseCase.GetCustomStatuses(ctx); err != nil {\n    var cause *StorageError\n    if errors.As(err, &cause) { /* handle storage-level failure */ }\n}","tryCatchPattern":"result, err := sweeper.Sweep(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"reading custom statuses\") {\n        // inspect errors.Unwrap(err) / errors.As for the config cause,\n        // restore connectivity, then retry the sweep\n    }\n    return err\n}","preventionTips":["Keep the Dolt backend reachable for the whole sweep (avoid network operations mid-run)","Keep the .beads schema at the version the binary expects; run bd doctor/migrations after upgrades","Avoid downgrading beads against a newer database schema","Monitor disk permissions on embedded database files"],"tags":["storage","config","sweep"],"backgroundTag":"config-read-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}