{"record":{"id":"73d28aa33811e049","repo":"gastownhall/beads","slug":"search-issues-with-counts-wisp-probe-w-73d28a","errorCode":null,"errorMessage":"search issues with counts: wisp probe: %w","messagePattern":"search issues with counts: wisp probe: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/search_counts.go","lineNumber":58,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn finishSearchIssuesWithCounts(out, filter)\n\t}\n\n\tout, err := runFilterSearchQueryInTx(ctx, tx, query, filter, IssuesFilterTables, wispDepsExist)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Skip wisps merge entirely when caller opts out (Q2: perf escape hatch).\n\tif filter.SkipWisps {\n\t\treturn finishSearchIssuesWithCounts(out, filter)\n\t}\n\n\tempty, probeErr := wispsTableEmptyOrMissingInTx(ctx, tx)\n\tif probeErr != nil {\n\t\treturn nil, fmt.Errorf(\"search issues with counts: wisp probe: %w\", probeErr)\n\t}\n\tif empty {\n\t\treturn finishSearchIssuesWithCounts(out, filter)\n\t}\n\tif !wispDepsExist {\n\t\treturn finishSearchIssuesWithCounts(out, filter)\n\t}\n\n\twisps, err := runFilterSearchQueryInTx(ctx, tx, query, filter, WispsFilterTables, true)\n\tif err != nil {\n\t\tif missingOptionalWispTable(err) {\n\t\t\treturn finishSearchIssuesWithCounts(out, filter)\n\t\t}\n\t\treturn nil, err\n\t}\n\tif len(wisps) == 0 {\n\t\treturn finishSearchIssuesWithCounts(out, filter)\n\t}","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/search_counts.go#L40-L76","documentation":"SearchIssuesWithCountsInTx wraps a failure of wispsTableEmptyOrMissingInTx on the default (non-ephemeral) path, after the durable issues query and unless filter.SkipWisps was set. The probe decides whether the wisps merge step is needed; if the probe query itself fails, the search aborts wrapped as 'wisp probe'.","triggerScenarios":"Calling SearchIssuesWithCountsInTx without SkipWisps where the wisps-table emptiness probe errors — lock contention, dropped connection, ctx cancellation, or a corrupted/inaccessible wisps table preventing even an existence/emptiness check.","commonSituations":"bd list/search --counts against a database where a crashed writer left the wisps table locked; remote Dolt server briefly unreachable; deadline exceeded on large remote stores.","solutions":["Unwrap the cause and address the driver-level failure (lock, connection, timeout)","Set filter.SkipWisps = true if you only need durable issues and can skip the wisps merge (explicit perf escape hatch)","Retry the search — probes are usually transient failures","Raise the context timeout for remote/slow stores","Run bd doctor to check DB integrity and table accessibility"],"exampleFix":"// before: durable-only consumer still paying for (and failing on) the wisp probe\nres, err := issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)\n// after: caller does not need wisps\nfilter.SkipWisps = true\nres, err := issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)","handlingStrategy":"fallback","validationCode":"// skip the wisp probe entirely when wisps are not needed\nif !needEphemeral {\n    filter.SkipWisps = true\n}","typeGuard":"func isWispProbeErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(),\n        \"search issues with counts: wisp probe: \")\n}","tryCatchPattern":"res, err := issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)\nif err != nil && isWispProbeErr(err) {\n    // fall back to durable-issues-only results\n    filter.SkipWisps = true\n    res, err = issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)\n}","preventionTips":["Set SkipWisps whenever you only consume durable issues","Keep short context deadlines off remote stores doing wisp merges","Retry transient probe failures on a fresh transaction","Run bd doctor if probe failures repeat"],"tags":["database","sql","wisps","schema-probe"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}