gastownhall/beads · error
iterate conflicts for table %s: %w
Error message
iterate conflicts for table %s: %w
What it means
GetConflictRows scanned all visible rows but rows.Err() returned an error during final iteration — meaning the row iterator hit a failure mid-stream (connection loss, server error, context cancellation) rather than completing normally. This is checked after the loop so partially collected data is discarded and the iteration failure is reported.
Source
Thrown at internal/storage/versioncontrolops/conflicts.go:144
cols, err := rows.Columns()
if err != nil {
return nil, fmt.Errorf("conflict columns for table %s: %w", table, err)
}
var out []storage.ConflictRow
for rows.Next() {
vals := make([]any, len(cols))
ptrs := make([]any, len(cols))
for i := range vals {
ptrs[i] = &vals[i]
}
if err := rows.Scan(ptrs...); err != nil {
return nil, fmt.Errorf("scan conflict row for table %s: %w", table, err)
}
out = append(out, buildConflictRow(table, cols, vals))
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate conflicts for table %s: %w", table, err)
}
return out, nil
}
// buildConflictRow re-presents one raw conflict row as fields. It is pure, so
// the column-splitting rules are unit-testable without a database.
func buildConflictRow(table string, cols []string, vals []any) storage.ConflictRow {
row := storage.ConflictRow{Table: table}
index := make(map[string]int, len(cols))
for i, col := range cols {
side, field, ok := splitConflictColumn(col)
if !ok {
continue
}
v := formatConflictValue(vals[i])
if conflictMetaSuffixes[field] {
if field == "diff_type" && v != nil {
switch side {View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped error for cancellation vs connection loss
- Increase the context timeout or re-run with a longer deadline
- Retry on a fresh connection; conflicts data is read-only so retry is safe
- Check dolt sql-server logs for query kills or restarts
Example fix
// before ctx := context.Background() // after ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel()
Defensive patterns
Strategy: retry
Try / catch
var rows []storage.ConflictRow
var err error
for attempt := 0; attempt < 3; attempt++ {
rows, err = versioncontrolops.GetConflictRows(ctx, db, table)
if err == nil || !isTransient(err) { break }
time.Sleep(backoff(attempt))
} Prevention
- Set generous context timeouts sized to table size
- Read conflicts on a dedicated healthy connection
- Treat iteration errors as safe-to-retry (read-only op)
When it happens
Trigger: The dolt connection drops or the query is aborted while GetConflictRows is iterating rows.Next(); context deadline exceeded mid-iteration; server-side kill of the running query.
Common situations: Long-running conflict scans over large conflicted tables hitting a context timeout; network instability between client and dolt sql-server; server restart during read.
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
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
- failed to query orphaned dependencies: %w
- row iteration error: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6890605393cc8e0c.
Report an issue: GitHub.