gastownhall/beads · error

search count %s: rows: %w

Error message

search count %s: rows: %w

What it means

Wraps rows.Err() after iterating a counts mega-query result set. This error surfaces problems detected during iteration — the connection dropped or the statement failed partway through streaming rows — rather than at query start. The %s names the main table of the failing counts query.

Source

Thrown at internal/storage/domain/db/issue_search_counts.go:204

	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", tables.Main, err)
	}
	return out, nil
}

func (r *issueSQLRepositoryImpl) optionalTableExists(ctx context.Context, table string) (bool, error) {
	var probe int
	//nolint:gosec // G201: table is a hardcoded constant from caller (issues, wisps, dependencies, wisp_dependencies, ...).
	err := r.runner.QueryRowContext(ctx, fmt.Sprintf("SELECT 1 FROM %s LIMIT 1", table)).Scan(&probe)
	switch {
	case err == nil:
		return true, nil
	case errors.Is(err, sql.ErrNoRows):
		return true, nil
	case dberrors.IsTableNotExist(err):
		return false, nil
	default:
		return false, err
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the query — mid-iteration drops are usually transient
  2. Reduce result size (filters, Lite hydration, pagination) to shorten iteration window
  3. Check DB server stability/logs for aborts
  4. Verify driver version compatibility

Example fix

// before
items, err := store.Search(ctx, bigFilter)
// after
items, err := store.Search(ctx, bigFilter)
if err != nil { items, err = store.Search(ctx, bigFilter) } // bounded retry for transient rows errors
Defensive patterns

Strategy: retry

Try / catch

items, err := store.Search(ctx, q, filter)
if err != nil && strings.Contains(err.Error(), "rows:") && isTransient(err) {
    time.Sleep(backoff)
    items, err = store.Search(ctx, q, filter)
}

Prevention

When it happens

Trigger: rows.Next() loop completes but rows.Err() is non-nil: mid-iteration network failure, server-side abort, or driver decode issue detected late.

Common situations: Long-running aggregate queries over big datasets losing their connection; remote Dolt server restarts mid-query; flaky network to a shared server.

Related errors


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