gastownhall/beads · error
search count %s: rows: %w
Error message
search count %s: rows: %w
What it means
scanCountsRowsInTx wraps the error from rows.Err() after iterating the counts result set. The counts query started fine and rows scanned (or were skipped as duplicate IDs), but the driver reported a failure at end-of-iteration — typically a mid-stream connection or server failure only visible once the result set is exhausted.
Source
Thrown at internal/storage/issueops/search_counts.go:180
var out []*types.IssueWithCounts
seen := make(map[string]bool)
for rows.Next() {
iwc, scanErr := ScanReadyWorkRowWithCounts(rows, hyd)
if scanErr != nil {
return nil, scanErr
}
if iwc == nil || iwc.Issue == nil {
continue
}
if seen[iwc.Issue.ID] {
continue
}
seen[iwc.Issue.ID] = true
out = append(out, iwc)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("search count %s: rows: %w", mainTable, err)
}
return out, nil
}
// finishSearchIssuesWithCounts is the single terminal hook every
// SearchIssuesWithCountsInTx exit path routes through: it sorts the merged
// result, applies the caller-facing Limit trim, and only then enforces the
// defensive MaxRows cap (be-x42v) on the delivered count — mirroring
// searchInTx's trimToSearchLimit-before-EnforceMaxRowsCap ordering and
// finishReadyWorkWithCounts in ready_work_counts.go.
//
// Trim-before-cap matters for the merged (issues+wisps) case:
// runFilterSearchQueryInTx sizes each leg's SQL LIMIT independently via
// EffectiveSearchLimit(filter.Limit, filter.MaxRows), so the merged
// pre-trim slice can hold up to ~2x that per-leg bound — e.g. Limit=2,
// MaxRows=5, 3 rows in each table merges to 6, which would trip MaxRows
// even though the page actually handed back to the caller (trimmed to
// Limit=2) is well within the cap. Checking the cap against the deliveredView on GitHub (pinned to 71377f2769)
Solutions
- Unwrap the rows error and retry if transient (reset connection, killed query)
- Raise the context timeout for large count scans
- Narrow the filter (status, assignee, limit) to shrink the scanned set
- Check server-side kill/timeout logs and raise them if they cut the query
- Ensure the process is not receiving signals/interrupts mid-scan (e.g. CI cancellation)
Example fix
// before: default deadline too short for a full-repo count scan ctx, cancel := context.WithTimeout(ctx, 2*time.Second) // after: size the deadline to the corpus ctx, cancel := context.WithTimeout(ctx, 60*time.Second) defer cancel() issues, err := issueops.SearchIssuesWithCounts(ctx, q, filter)
Defensive patterns
Strategy: retry
Validate before calling
// sanity-check scope before a long count scan
if ctx.Err() != nil { return ctx.Err() }
if filter.Limit == 0 && filter.MaxRows == 0 && corpusIsLarge() {
filter.MaxRows = 10000 // cap the scan
} Type guard
func isCountsRowsErr(err error) bool {
return err != nil && strings.Contains(err.Error(), ": rows: ") &&
strings.HasPrefix(err.Error(), "search count ")
} Try / catch
var res []*types.IssueWithCounts
var err error
for attempt := 0; attempt < 3; attempt++ {
res, err = issueops.SearchIssuesWithCounts(ctx, q, filter)
if err == nil || !isCountsRowsErr(err) { break }
time.Sleep(backoff(attempt))
}
if err != nil { return err } Prevention
- Set context timeouts proportional to corpus size
- Cap scans with filter.MaxRows on large databases
- Raise server-side query timeouts for count projections
- Avoid CI cancellation signals mid-scan; checkpoint large count jobs
When it happens
Trigger: During iteration of the count-projection SELECT in runReadyCountsInTx/runSearchQueryInTx, the connection breaks, the server kills the query, or ctx is cancelled between Next() calls; the deferred error is surfaced via rows.Err() and wrapped with the main table name.
Common situations: Long-running count queries over large corpora hitting a server-side timeout; network blip to a remote Dolt server; SQLite interrupted by a process signal mid-scan.
Related errors
- db: ChildCounterSQLRepository.NextChildID: rows: %w
- db: CommentSQLRepository.CountsByIssueIDs: rows: %w
- db: CommentSQLRepository.ListByIssueIDs: rows: %w
- db: RawSQL Query: rows: %w
- db: ListRemotes: rows: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0590b12a69ec00c7.
Report an issue: GitHub.