gastownhall/beads · error
stale issues rows: %w
Error message
stale issues rows: %w
What it means
After iterating rows, GetStaleIssuesInTx calls rows.Err() to detect failures that occurred during row iteration and wraps it with 'stale issues rows: %w'. This means the connection dropped or the query was aborted partway through streaming the stale issue ids — not a query-preparation or scan problem.
Source
Thrown at internal/storage/issueops/stale.go:83
if err != nil {
return nil, fmt.Errorf("failed to get stale issues: %w", err)
}
// Collect IDs first, then batch-fetch full issues.
// Close rows explicitly before the nested fetch — MySQL/Dolt drivers
// can't handle multiple active result sets on one connection.
var ids []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
rows.Close()
return nil, fmt.Errorf("failed to scan stale issue id: %w", err)
}
ids = append(ids, id)
}
if err := rows.Err(); err != nil {
rows.Close()
return nil, fmt.Errorf("stale issues rows: %w", err)
}
rows.Close()
if len(ids) == 0 {
return nil, nil
}
// GetIssuesByIDsInTx returns issues in arbitrary order (WHERE IN),
// so re-order to preserve the updated_at ASC ordering from the query.
issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)
if err != nil {
return nil, err
}
issueByID := make(map[string]*types.Issue, len(issues))
for _, iss := range issues {
if iss != nil {
issueByID[iss.ID] = issView on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped driver error to distinguish connection-lost vs context cancelled.
- Retry the whole operation with a fresh transaction and connection — iteration errors are typically transient.
- Increase client/server idle and read timeouts if scans of large tables routinely exceed them.
- Keep the ctx deadline generous enough for the row count expected, and avoid sharing the tx across goroutines.
Example fix
// before
issues, err := GetStaleIssuesInTx(ctx, tx, filter) // dies mid-iteration on slow network
// after
for attempt := 0; attempt < 3; attempt++ {
issues, err = GetStaleIssuesInTx(ctx, tx, filter)
if err == nil { break }
time.Sleep(time.Second * time.Duration(attempt+1))
} Defensive patterns
Strategy: retry
Validate before calling
// ensure the connection is healthy before a long streaming scan
if err := tx.PingContext(ctx); err != nil { return fmt.Errorf("connection unhealthy: %w", err) } Try / catch
issues, err := issueops.GetStaleIssuesInTx(ctx, tx, filter)
if err != nil && strings.Contains(err.Error(), "stale issues rows:") {
// transient iteration failure: reopen tx and retry with backoff
} Prevention
- Set generous idle/read timeouts on the Dolt/MySQL connection
- Avoid sweeping huge tables over flaky networks; run locally or batch
- Don't share a tx across goroutines during iteration
- Give the ctx enough budget for the expected row count
When it happens
Trigger: Network interruption to the Dolt/MySQL server while rows are being streamed; server-side query kill or timeout during iteration; context cancellation while rows.Next() is advancing; connection closed by the pool mid-iteration.
Common situations: Long stale scans over big issues tables hitting an idle-connection timeout; flaky network to a remote Dolt server; server restarts during a sweep/stale job; proxy/load-balancer idle timeouts.
Related errors
- iterate inbound dependencies from %s: %w
- row iteration error: %w
- get dependency records: rows: %w
- remaining blocker rows from %s: %w
- blocker edge rows from %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/eb88c8c37eb9996c.
Report an issue: GitHub.