gastownhall/beads · error
search issues: %w
Error message
search issues: %w
What it means
searchAcrossIssuesAndWisps wraps a failure from searchTable against the durable issues table when filter.SkipWisps is set. This is the issues-only search path: any SQL execution, scan, or hydration error from searching the issues table is wrapped as "search issues". The issues table is mandatory, so no table-not-exist tolerance applies.
Source
Thrown at internal/storage/domain/db/issue_search.go:53
name, ok := dberrors.MissingTableName(err)
return ok && sqlbuild.OptionalWispTable(name)
}
func (r *issueSQLRepositoryImpl) searchAcrossIssuesAndWisps(ctx context.Context, query string, filter types.IssueFilter) (domain.SearchPage, error) {
if filter.Ephemeral != nil && *filter.Ephemeral {
page, err := r.searchTable(ctx, query, filter, wispsFilterTables)
if err != nil && !missingOptionalWispTable(err) {
return domain.SearchPage{}, fmt.Errorf("search wisps (ephemeral filter): %w", err)
}
if len(page.Items) > 0 {
return page, nil
}
}
if filter.SkipWisps {
page, err := r.searchTable(ctx, query, filter, issuesFilterTables)
if err != nil {
return domain.SearchPage{}, fmt.Errorf("search issues: %w", err)
}
return page, nil
}
empty, probeErr := r.wispsTableEmptyOrMissing(ctx)
if probeErr != nil {
return domain.SearchPage{}, fmt.Errorf("search wisps (merge): probe: %w", probeErr)
}
if empty {
page, err := r.searchTable(ctx, query, filter, issuesFilterTables)
if err != nil {
return domain.SearchPage{}, fmt.Errorf("search issues: %w", err)
}
return page, nil
}
return r.searchUnion(ctx, query, filter)
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped inner error (search issues: <table>: ...) to find the failing statement
- Simplify the query/filter to isolate which clause breaks; check for characters or fields the filter builder mishandles
- Run bd doctor to verify mandatory tables (issues, labels, dependencies) exist
- Retry on transient connection errors and check Dolt server health
Example fix
// before: opaque filter passed straight through
page, err := store.Search(ctx, rawUserQuery, userFilter)
// after: validate/limit the filter first
if userFilter.MaxRows == 0 { userFilter.MaxRows = 1000 }
page, err := store.Search(ctx, rawUserQuery, userFilter) Defensive patterns
Strategy: try-catch
Try / catch
page, err := store.Search(ctx, q, types.IssueFilter{SkipWisps: true})
if err != nil && strings.Contains(err.Error(), "search issues") {
var tbl string
if name, ok := dberrors.MissingTableName(errors.Unwrap(err)); ok {
tbl = name
// missing mandatory table: repair via bd doctor / restore
}
} Prevention
- Validate user-supplied query/filter input before passing to Search
- Run bd doctor after any schema-affecting operation
- Set sane MaxRows limits on user-triggered searches
- Handle transient connection errors with bounded retries
When it happens
Trigger: Calling SearchAcrossIssuesAndWisps with SkipWisps=true when the issues-table search fails: bad query/filter combination producing invalid SQL, missing labels/dependencies tables during hydration, connection drop, or ctx cancellation.
Common situations: Search strings or filter values that break clause building; databases missing the labels or dependencies table; Dolt server unreachable; oversized result sets hitting the MaxRows cap in combination with other errors.
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
- search %s: %w
- search %s: %w
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/54114c75ce82b68f.
Report an issue: GitHub.