gastownhall/beads · error

query conflicts for table %s: %w

Error message

query conflicts for table %s: %w

What it means

GetConflictRows failed while executing the SELECT against the dolt_conflicts_<table> system table. This wraps the underlying driver error, meaning the query itself could not be executed — the table name was already validated as an identifier, so the failure comes from dolt or the connection. The wrapped cause (%w) carries the real reason.

Source

Thrown at internal/storage/versioncontrolops/conflicts.go:122

	case time.Time:
		s = t.UTC().Format(time.RFC3339)
	default:
		s = fmt.Sprint(t)
	}
	return &s
}

// GetConflictRows returns the live conflicted rows of table, one entry per
// conflicted row with its columns presented per field. It reads the working
// set: a merge whose conflicts were aborted (the auto-settle path) leaves
// nothing here, which is correct — those conflicts no longer exist.
func GetConflictRows(ctx context.Context, db DBConn, table string) ([]storage.ConflictRow, error) {
	if err := ValidateConflictTable(table); err != nil {
		return nil, err
	}
	rows, err := db.QueryContext(ctx, "SELECT * FROM `dolt_conflicts_"+table+"`") //nolint:gosec // table validated as an identifier above
	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)
		}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped driver error (%w) for the root cause — missing table vs connection failure
  2. Confirm a merge with conflicts actually happened (e.g. via dolt_conflicts or merge status) before calling GetConflictRows
  3. Verify the connection is alive and the session is still open
  4. Check dolt version supports the dolt_conflicts_<table> system table

Example fix

// before
rows, err := versioncontrolops.GetConflictRows(ctx, db, "issues") // assumes conflicts exist
// after
if ok, _ := versioncontrolops.HasConflicts(ctx, db, "issues"); ok {
    rows, err := versioncontrolops.GetConflictRows(ctx, db, "issues")
}
Defensive patterns

Strategy: try-catch

Validate before calling

var n int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM `dolt_conflicts_` + table").Scan(&n); err != nil || n == 0 {
    return nil, nil // no conflicts to read
}

Try / catch

rows, err := versioncontrolops.GetConflictRows(ctx, db, table)
if err != nil {
    if strings.Contains(err.Error(), "doesn't exist") {
        return nil, nil // treat as no conflicts
    }
    return fmt.Errorf("get conflict rows: %w", err)
}

Prevention

When it happens

Trigger: Calling GetConflictRows(ctx, db, table) when the underlying dolt_conflicts_<table> system table does not exist (no conflict for that table), when the connection is broken/closed, or when the session lacks permission to query the conflicts table.

Common situations: Querying conflicts after the merge was fully resolved (conflict rows already cleared); querying a table that never had a merge conflict; connection dropped mid-session or pool checkout failure; running against an older dolt version that names conflicts tables differently.

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/dfaa139d91abe297. Report an issue: GitHub.