{"record":{"id":"198da8a50961e291","repo":"gastownhall/beads","slug":"search-wisps-merge-probe-w","errorCode":null,"errorMessage":"search wisps (merge): probe: %w","messagePattern":"search wisps \\(merge\\): probe: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/issue_search.go","lineNumber":60,"sourceCode":"\t\tif err != nil && !missingOptionalWispTable(err) {\n\t\t\treturn domain.SearchPage{}, fmt.Errorf(\"search wisps (ephemeral filter): %w\", err)\n\t\t}\n\t\tif len(page.Items) > 0 {\n\t\t\treturn page, nil\n\t\t}\n\t}\n\n\tif filter.SkipWisps {\n\t\tpage, err := r.searchTable(ctx, query, filter, issuesFilterTables)\n\t\tif err != nil {\n\t\t\treturn domain.SearchPage{}, fmt.Errorf(\"search issues: %w\", err)\n\t\t}\n\t\treturn page, nil\n\t}\n\n\tempty, probeErr := r.wispsTableEmptyOrMissing(ctx)\n\tif probeErr != nil {\n\t\treturn domain.SearchPage{}, fmt.Errorf(\"search wisps (merge): probe: %w\", probeErr)\n\t}\n\tif empty {\n\t\tpage, err := r.searchTable(ctx, query, filter, issuesFilterTables)\n\t\tif err != nil {\n\t\t\treturn domain.SearchPage{}, fmt.Errorf(\"search issues: %w\", err)\n\t\t}\n\t\treturn page, nil\n\t}\n\n\treturn r.searchUnion(ctx, query, filter)\n}\n\nfunc (r *issueSQLRepositoryImpl) searchUnion(ctx context.Context, query string, filter types.IssueFilter) (domain.SearchPage, error) {\n\touterOrderBy := unionOrderBySQL(filter.SortBy, filter.SortDesc)\n\twindow := searchWindowForFilter(filter)\n\tlegWindow := legWindowSQL(outerOrderBy, window)\n\n\tiSub, iArgs, err := r.buildUnionSubquery(query, filter, issuesFilterTables, \"i\", legWindow)","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/issue_search.go#L42-L78","documentation":"In the merge path (no Ephemeral, no SkipWisps), searchAcrossIssuesAndWisps probes whether the wisps table is empty or missing via wispsTableEmptyOrMissing before deciding between an issues-only search and a UNION search. A probe error that is neither sql.ErrNoRows nor table-not-exist — connection failure, permissions, engine error — is wrapped as \"search wisps (merge): probe\".","triggerScenarios":"Calling SearchAcrossIssuesAndWisps without SkipWisps when `SELECT 1 FROM wisps LIMIT 1` fails with a real error: server unreachable mid-command, denied SELECT on wisps, corrupted database file, or driver-level failure.","commonSituations":"Dolt server restart during a bd query; read-only user lacking grants on wisps; disk/database corruption; stale connections after a network interruption.","solutions":["Check database connectivity and Dolt server logs; run bd doctor","Retry the search — the probe runs early and transient drops are the most common cause","Verify the bd user has SELECT grants on the wisps table","Use SkipWisps=true to skip the probe entirely if you only need durable issues"],"exampleFix":"// before: merge path always probes wisps\npage, err := store.Search(ctx, q, types.IssueFilter{})\n// after: skip the wisp plane when it is not needed\npage, err := store.Search(ctx, q, types.IssueFilter{SkipWisps: true})","handlingStrategy":"retry","validationCode":"if err := store.Ping(ctx); err != nil {\n    return fmt.Errorf(\"store down, skipping search: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"page, err := store.Search(ctx, q, filter)\nif err != nil && strings.Contains(err.Error(), \"search wisps (merge): probe\") {\n    // probe failed on a real error: retry, then fall back to SkipWisps\n    page, err = store.Search(ctx, q, types.IssueFilter{SkipWisps: true})\n}","preventionTips":["Health-check connectivity before issuing searches during incidents","Ensure the bd user has SELECT on wisps","Monitor Dolt server availability; probe failures usually follow restarts","Use SkipWisps=true to avoid the probe when wisps are irrelevant"],"tags":["database","probe","wisps","connectivity"],"backgroundTag":"database-connection-lost","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}