{"record":{"id":"652cff3076213ef0","repo":"gastownhall/beads","slug":"ready-work-union-with-counts-hydrate-wisps-w","errorCode":null,"errorMessage":"ready work union with counts: hydrate wisps: %w","messagePattern":"ready work union with counts: hydrate wisps: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/ready_work_union.go","lineNumber":129,"sourceCode":"\t}\n\n\tpage, hasMore, err := r.getReadyWorkIDPage(ctx, filter)\n\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, err\n\t}\n\tif len(page.ordered) == 0 {\n\t\treturn domain.SearchCountsPage{Items: nil, HasMore: hasMore}, nil\n\t}\n\n\tissuesByID, err := r.fetchCountsByIDs(ctx, page.issueIDs, issuesFilterTables, wispDepsExist, readyHydrationFor(filter))\n\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"ready work union with counts: hydrate issues: %w\", err)\n\t}\n\tvar wispsByID map[string]*types.IssueWithCounts\n\tif len(page.wispIDs) > 0 {\n\t\twispsByID, err = r.fetchCountsByIDs(ctx, page.wispIDs, wispsFilterTables, true, readyHydrationFor(filter))\n\t\tif err != nil && !dberrors.IsTableNotExist(err) {\n\t\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"ready work union with counts: hydrate wisps: %w\", err)\n\t\t}\n\t}\n\n\treturn domain.SearchCountsPage{\n\t\tItems:   reassembleBySrc(page.ordered, issuesByID, wispsByID),\n\t\tHasMore: hasMore,\n\t}, nil\n}\n","sourceCodeStart":111,"sourceCodeEnd":138,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/ready_work_union.go#L111-L138","documentation":"This error wraps a failure that occurred while hydrating wisp rows (lightweight issues) with their issue counts during the 'ready work with counts' union query. The union query already fetched the paged IDs; hydration via fetchCountsByIDs then queries per-table count data. Any SQL error other than a benign 'table does not exist' is wrapped here, so the message indicates the underlying Dolt/SQL error after 'hydrate wisps:'.","triggerScenarios":"Calling GetReadyWorkWithCounts when the result page contains wisp IDs and fetchCountsByIDs fails with a SQL error that is not dberrors.IsTableNotExist — e.g. malformed wispsFilterTables, connection drop mid-query, SQL syntax/permission error, or context cancellation during the count hydration query.","commonSituations":"Upgraded or partially migrated database where wisp count tables are corrupt or inaccessible; transient Dolt server connection loss; query timeout/cancelled context while loading the ready-work board with counts; schema drift between beads version and database.","solutions":["Read the wrapped cause after 'hydrate wisps:' to identify the real SQL error","Check database schema integrity (run bd doctor / migrations) to ensure wisp count tables exist and are valid","Retry the operation if the cause is a transient connection/timeout error","If a required table is genuinely missing, run the schema migration instead of expecting hydration to skip it (only missing tables are tolerated)"],"exampleFix":"// before\npage, err := store.GetReadyWorkWithCounts(ctx, filter)\nif err != nil { return err }\n// after\npage, err := store.GetReadyWorkWithCounts(ctx, filter)\nif err != nil {\n    if dberrors.IsTableNotExist(errors.Unwrap(errors.Unwrap(err))) { /* treat as empty counts */ }\n    log.Errorf(\"ready work counts failed: %v\", err)\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// verify DB connectivity and schema before calling\nif err := pingDB(ctx); err != nil { return err }\n// note: missing wisp count tables are tolerated internally (IsTableNotExist)","typeGuard":"func isHydrationErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"hydrate wisps:\")\n}","tryCatchPattern":"page, err := store.GetReadyWorkWithCounts(ctx, filter)\nif err != nil {\n    var cause error\n    for errors.Unwrap(err) != nil { cause = errors.Unwrap(err) }\n    if dberrors.IsTableNotExist(cause) { /* fall back to no-counts query */ }\n    return fmt.Errorf(\"ready work unavailable: %w\", err)\n}","preventionTips":["Keep schema migrations current with the beads version","Use contexts with adequate timeouts for ready-work queries","Monitor Dolt server health before board refreshes"],"tags":["database","sql","hydration","query"],"backgroundTag":"sql-hydration-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}