{"record":{"id":"f11a9492e0bfa96e","repo":"gastownhall/beads","slug":"search-union-with-counts-hydrate-issues-w","errorCode":null,"errorMessage":"search union with counts (hydrate issues): %w","messagePattern":"search union with counts \\(hydrate issues\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/issue_search_counts.go","lineNumber":103,"sourceCode":"\targs = append(args, wArgs...)\n\n\trows, err := r.runner.QueryContext(ctx, unionSQL, args...)\n\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"search union with counts: %w\", err)\n\t}\n\tpage, err := scanIDSrcPage(rows)\n\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"search union with counts: %w\", err)\n\t}\n\tpage.sortGoSide(filter.SortBy, filter.SortDesc)\n\thasMore, err := page.finishWindow(window)\n\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, err\n\t}\n\n\tissuesByID, err := r.fetchCountsByIDs(ctx, page.issueIDs, issuesFilterTables, wispDepsExist, hydrationFor(filter))\n\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"search union with counts (hydrate issues): %w\", err)\n\t}\n\twispsByID, err := r.fetchCountsByIDs(ctx, page.wispIDs, wispsFilterTables, true, hydrationFor(filter))\n\tif err != nil && !missingOptionalWispTable(err) {\n\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"search union with counts (hydrate wisps): %w\", err)\n\t}\n\n\tout := reassembleBySrc(page.ordered, issuesByID, wispsByID)\n\treturn domain.SearchCountsPage{Items: out, HasMore: hasMore}, nil\n}\n\n// hydrationFor reads the hydration opt-outs off a search filter, matching the\n// store-backed path's helper of the same name (internal/storage/issueops).\n// Both bodies must read the same fields off the same filter or a caller that\n// set one would get different columns from the two backends.\nfunc hydrationFor(filter types.IssueFilter) sqlbuild.CountsHydration {\n\treturn sqlbuild.CountsHydration{SkipLabels: filter.SkipLabels, SkipCounts: filter.SkipCounts, Lite: filter.Lite}\n}\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/issue_search_counts.go#L85-L121","documentation":"Wraps failures from fetchCountsByIDs when hydrating counts (labels, dependencies, etc.) for the issue IDs on the union page. The hydration uses the by-IDs counts mega-query with chunked IDs; failures here mean the follow-up hydration SQL failed, not the main search.","triggerScenarios":"After the union page is built, fetchCountsByIDs for page.issueIDs fails — engine error in the counts mega-query, context cancellation, or chunked placeholder issues.","commonSituations":"Timeouts during hydration of large pages, schema issues in dependency/label tables, or DB connection drops between the search and hydration queries.","solutions":["Inspect the inner 'search count issues' error for the engine message","Reduce page size / skip hydration via filter.SkipCounts or filter.Lite to shrink the mega-query","Verify dependencies/labels tables exist and schema matches","Retry on transient connection errors"],"exampleFix":"// before\nfilter := types.IssueFilter{...}\n// after\nfilter.SkipCounts = true // or filter.Lite = true to lighten hydration","handlingStrategy":"fallback","validationCode":"if page.ItemCount > largePageThreshold {\n    filter.Lite = true // shrink hydration before calling\n}","typeGuard":null,"tryCatchPattern":"page, err := store.SearchWithCounts(ctx, q, filter)\nif err != nil && strings.Contains(err.Error(), \"hydrate issues\") {\n    filter.SkipCounts = true\n    page, err = store.SearchWithCounts(ctx, q, filter) // degrade gracefully\n}","preventionTips":["Offer Lite/SkipCounts modes for big pages","Set generous hydration timeouts","Keep dependency/label table schemas migrated","Chunk hydration by IDs (as the library does) and monitor chunk failures"],"tags":["sql","hydration","search"],"backgroundTag":"sql-query-execution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}