{"record":{"id":"8163300f78403f1e","repo":"gastownhall/beads","slug":"search-union-with-counts-w","errorCode":null,"errorMessage":"search union with counts: %w","messagePattern":"search union with counts: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/issue_search_counts.go","lineNumber":89,"sourceCode":"\tif err != nil {\n\t\treturn domain.SearchCountsPage{}, fmt.Errorf(\"search union with counts (wisps): %w\", err)\n\t}\n\n\t// EACH LEG IS PARENTHESIZED, and it is not decoration. A leg that carries\n\t// its own ORDER BY and LIMIT (legWindowSQL) is a syntax error inside a bare\n\t// UNION ALL — the engine reads the clause as belonging to the union — so the\n\t// parentheses are what let the window be pushed down at all.\n\t//nolint:gosec // G201: subqueries built from hardcoded table names and ? placeholders.\n\tunionSQL := fmt.Sprintf(\"SELECT id, src FROM ((%s) UNION ALL (%s)) merged %s %s\",\n\t\tiSub, wSub, outerOrderBy, window.sql)\n\n\targs := make([]any, 0, len(iArgs)+len(wArgs))\n\targs = append(args, iArgs...)\n\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)","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/issue_search_counts.go#L71-L107","documentation":"Wraps the database/sql error from QueryContext running the combined issues+wisps UNION ALL query. At this point SQL text and args are fully built, so the failure is at the engine: syntax, unknown table/column, connection loss, or placeholder/arg mismatch (iArgs then wArgs must match the leg order).","triggerScenarios":"QueryContext on the union SQL fails — driver-level error such as 'no such table', SQL syntax error, too many parameters, or context cancellation/timeouts mid-query.","commonSituations":"Dolt/SQLite schema missing wisp tables probed as existing earlier, oversized result sets hitting parameter or packet limits, network drop to remote Dolt server, or query cancelled by client timeout.","solutions":["Check the wrapped driver error for the concrete engine message","Verify both issues and wisps tables exist and match the expected schema (bd doctor / schema migration)","Retry on transient network errors; increase context timeout for large searches","If it's an arg/placeholder mismatch, ensure buildUnionSubquery argument counts match each leg's placeholders"],"exampleFix":"// before\nctx := context.Background()\n// after\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel() // and retry once on transient net errors","handlingStrategy":"retry","validationCode":"if err := ensureSchemaCurrent(ctx, db); err != nil {\n    return fmt.Errorf(\"run bd migrations first: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"page, err := store.SearchWithCounts(ctx, q, filter)\nif err != nil && isTransient(err) {\n    select {\n    case <-time.After(backoff):\n        page, err = store.SearchWithCounts(ctx, q, filter)\n    default:\n    }\n}","preventionTips":["Use a context timeout sized for large union searches","Keep schema migrations current for both issues and wisps tables","Bound retries to transient network errors only","Monitor DB connection health for remote Dolt servers"],"tags":["sql","database","union-query","network"],"backgroundTag":"sql-query-execution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}