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

  1. Inspect the wrapped error for cancellation vs connection loss
  2. Increase the context timeout or re-run with a longer deadline
  3. Retry on a fresh connection; conflicts data is read-only so retry is safe
  4. 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

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


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