gastownhall/beads · error
scan conflict row for table %s: %w
Error message
scan conflict row for table %s: %w
What it means
GetConflictRows read column metadata fine but failed while scanning one conflict row into the value buffers. rows.Scan returns an error when the number of destination pointers does not match the column count or when a value's type cannot be converted into the destination. The library allocates one generic any pointer per column, so this usually signals a driver scan/convert failure.
Source
Thrown at internal/storage/versioncontrolops/conflicts.go:139
if err != nil {
return nil, fmt.Errorf("query conflicts for table %s: %w", table, err)
}
defer func() { _ = rows.Close() }()
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 {
continueView on GitHub (pinned to 71377f2769)
Solutions
- Re-run the query after ensuring no concurrent schema changes are happening
- Check the wrapped error for which column failed to convert
- Verify the dolt server and driver versions match
- Re-trigger the merge to regenerate clean conflict rows if they appear corrupted
Defensive patterns
Strategy: try-catch
Try / catch
rows, err := versioncontrolops.GetConflictRows(ctx, db, table)
if err != nil {
if strings.Contains(err.Error(), "scan conflict row") {
return fmt.Errorf("conflict schema changed; re-run merge: %w", err) // schema drift: don't blind-retry
}
return err
} Prevention
- Avoid concurrent DDL on conflicted tables
- Keep dolt server and driver versions aligned
- Alert on scan errors — they indicate schema/compat drift, not transient faults
When it happens
Trigger: A conflict row contains a value the driver cannot scan into *any (rare) or the number of columns changed between Columns() and Scan (schema drift, concurrent DDL); nil handling or driver-level conversion errors on unusual column types.
Common situations: Schema of the user table changed while conflicts were being read; dolt version mismatch producing unexpected system-column types in dolt_conflicts_<table>; corrupted or partially-written conflict rows after a crash.
Related errors
- failed to scan diff: %w
- ErrScan
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/969791f3682f76d3.
Report an issue: GitHub.