gastownhall/beads · error

search issues with counts: wisp dependency probe: %w

Error message

search issues with counts: wisp dependency probe: %w

What it means

SearchIssuesWithCountsInTx wraps a failure of the optionalTableExistsInTx probe for the wisp_dependencies table. Before searching with counts, the function checks whether this optional table exists so it can decide whether to merge ephemeral wisps; if the probe query itself fails, the whole search aborts with this wrapper.

Source

Thrown at internal/storage/issueops/search_counts.go:16

package issueops

import (
	"context"
	"database/sql"
	"fmt"
	"sort"

	"github.com/steveyegge/beads/internal/storage/sqlbuild"
	"github.com/steveyegge/beads/internal/types"
)

func SearchIssuesWithCountsInTx(ctx context.Context, tx *sql.Tx, query string, filter types.IssueFilter) ([]*types.IssueWithCounts, error) {
	wispDepsExist, err := optionalTableExistsInTx(ctx, tx, "wisp_dependencies")
	if err != nil {
		return nil, fmt.Errorf("search issues with counts: wisp dependency probe: %w", err)
	}

	if filter.Ephemeral != nil && *filter.Ephemeral {
		empty, probeErr := wispsTableEmptyOrMissingInTx(ctx, tx)
		if probeErr != nil {
			return nil, fmt.Errorf("search issues with counts: ephemeral wisp probe: %w", probeErr)
		}
		if !empty && wispDepsExist {
			wisps, err := runFilterSearchQueryInTx(ctx, tx, query, filter, WispsFilterTables, true)
			if err != nil && !missingOptionalWispTable(err) {
				return nil, err
			}
			if len(wisps) > 0 {
				return finishSearchIssuesWithCounts(wisps, filter)
			}
		}
		// Fall through: the wisps tier is missing/empty or matched no rows.
		// Mirror SearchIssuesInTx / CountIssuesInTx so count-projection searches

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the cause: it is a metadata-probe SQL failure, not a missing-table condition (missing is handled, failing is not)
  2. Check DB file integrity and locks (bd doctor; lsof on the .db file)
  3. Retry on a fresh connection if the connection was broken
  4. Raise the context timeout if the probe was cancelled by a deadline
  5. Run schema validation/repair; restore from backup if the catalog is corrupt

Example fix

// before: 1s deadline killed the table-existence probe
ctx, cancel := context.WithTimeout(ctx, time.Second)
// after: allow the probe + search to complete
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
iwcs, err := issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)
Defensive patterns

Strategy: try-catch

Validate before calling

// verify DB accessibility before count searches
if err := tx.PingContext(ctx); err != nil {
    return fmt.Errorf("db unreachable for count search: %w", err)
}

Type guard

func isWispDepProbeErr(err error) bool {
    return err != nil && strings.Contains(err.Error(),
        "search issues with counts: wisp dependency probe: ")
}

Try / catch

res, err := issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)
if err != nil && isWispDepProbeErr(err) {
    if errors.Is(err, context.DeadlineExceeded) {
        ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
        defer cancel()
        res, err = issueops.SearchIssuesWithCountsInTx(ctx, tx, q, filter)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling SearchIssuesWithCountsInTx (bd search --counts path) where the schema-introspection query (e.g. querying sqlite_master / information_schema) errors — locked DB, ctx cancelled, corrupted catalog, or driver failure.

Common situations: Corrupted or locked SQLite file; Dolt server connection failure during introspection; context deadline hit before the first real query; unusual DB created without the expected catalog access.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/21c57c5f0e39da5f. Report an issue: GitHub.