gastownhall/beads · error

query conflicts for table %s: %w

Error message

query conflicts for table %s: %w

What it means

loadConflictRows queries the dolt_conflicts_<table> system table during auto-merge conflict inspection; this error wraps the QueryContext failure. The table name is validated as an identifier first, so the failure is almost always on the SQL/engine side, not injection-related. It propagates to callers deciding whether merge conflicts can be auto-resolved.

Source

Thrown at internal/storage/versioncontrolops/automerge.go:100

	ourKey  any
	columns []string
	values  []any
	// lww names the cells both sides changed differently, which were settled
	// by timestamp rather than merged. They are the only cells where one
	// side's edit is superseded, so the resolver names them on stderr — the
	// same courtesy the config path pays for an otherwise-undiagnosable
	// supersession.
	lww []string
}

// loadConflictRows reads every live conflict row of table in raw scanned form.
func loadConflictRows(ctx context.Context, db DBConn, table string) ([]rawConflictRow, 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 []rawConflictRow
	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, rawConflictRow{cols: cols, vals: vals})

View on GitHub (pinned to 71377f2769)

Solutions

  1. Confirm a merge with conflicts is actually in progress (the conflicts table only exists/readable with live conflicts)
  2. Read the wrapped cause for the real SQL error and fix it
  3. Re-run or re-enter the merge so the conflict set is materialized, then retry auto-resolve
  4. Check Dolt server connectivity and version compatibility

Example fix

// before: resolving without checking merge state
err := versioncontrolops.TryAutoResolveMergeConflicts(ctx, db)
// after: only call when the merge left live conflicts
if inConflictedMergeState(ctx, db) {
    err = versioncontrolops.TryAutoResolveMergeConflicts(ctx, db)
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Only attempt auto-resolve when a conflicted merge is actually live
var n int
if err := db.QueryRowContext(ctx,
    "SELECT COUNT(*) FROM dolt_conflicts_issues").Scan(&n); err != nil || n == 0 {
    return fmt.Errorf("no live issues conflicts; skip auto-resolve")
}

Type guard

func hasLiveConflicts(ctx context.Context, db DBConn, table string) bool {
    rows, err := db.QueryContext(ctx, "SELECT 1 FROM `dolt_conflicts_`"+table+" LIMIT 1")
    if err != nil { _ = rows; return false }
    defer rows.Close()
    return rows.Next()
}

Try / catch

err := versioncontrolops.TryAutoResolveMergeConflicts(ctx, db)
if err != nil {
    var merr *MergeConflictsError
    if errors.As(err, nil) || strings.Contains(err.Error(), "query conflicts for table") {
        // fall back to manual DOLT_CONFLICTS_RESOLVE --ours/--theirs
    }
    return err
}

Prevention

When it happens

Trigger: TryAutoResolveMergeConflicts runs after a dolt merge with conflicts and `SELECT * FROM dolt_conflicts_issues` (or labels/comments/events) fails — no active conflict set (querying a conflicts table when no merge conflict exists), SQL syntax/engine error, or connection failure.

Common situations: Calling auto-resolve outside an active conflicted merge state; Dolt version where the conflicts system table is locked or unavailable; dropped connection to the Dolt server mid-resolution.

Related errors


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