gastownhall/beads · error
failed to resolve %s conflicts: %w
Error message
failed to resolve %s conflicts: %w
What it means
This error wraps a failure from the Dolt stored procedure CALL DOLT_CONFLICTS_RESOLVE('--theirs', table) inside TryAutoResolveMergeConflicts. The routine resolves merge conflicts for a hardcoded bead table by taking the incoming ('--theirs') version of every conflicted row. If the SQL call errors — bad table name, no active conflict state, or a Dolt engine failure — it is wrapped with the table name so the caller knows which table's conflicts could not be resolved.
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:560
}
if _, err := db.ExecContext(ctx, "CALL DOLT_CONFLICTS_RESOLVE('--theirs', 'config')"); err != nil {
return false, fmt.Errorf("failed to resolve config conflicts: %w", err)
}
case "issues":
// Field-level three-way merge, not a table-level --ours/--theirs:
// a cell only one side changed keeps that side's value and only a
// genuinely contested cell falls to LWW (automerge.go).
if err := resolveIssuesFieldMerge(ctx, db, issuesPlan); err != nil {
return false, err
}
case "labels", "comments", "events":
if err := resolveUnionConflicts(ctx, db, table, unionPlans[table]); err != nil {
return false, err
}
default:
//nolint:gosec // G201: table is one of the hardcoded constants above.
if _, err := db.ExecContext(ctx, "CALL DOLT_CONFLICTS_RESOLVE('--theirs', '"+table+"')"); err != nil {
return false, fmt.Errorf("failed to resolve %s conflicts: %w", table, err)
}
}
//nolint:gosec // G201: table is one of the hardcoded constants above.
if _, err := db.ExecContext(ctx, "CALL DOLT_ADD('"+table+"')"); err != nil {
return false, fmt.Errorf("failed to stage %s: %w", table, err)
}
}
return true, nil
}
// CommitResolvedConflicts creates the dolt commit that concludes a merge whose
// conflicts TryAutoResolveMergeConflicts settled. Callers that saw
// resolved=true MUST call this, and only AFTER TryRepairFKCascadeViolations
// has run: DOLT_COMMIT refuses a working set with outstanding constraint
// violations, so a merge carrying both an auto-resolvable conflict and an FK
// cascade violation could never settle while the resolver committed first
// (bd-578h9.14).View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the merge from a clean state: ensure the working set is in a conflicted merge (check dolt_status / dolt_conflicts) before calling SettleMerge.
- Verify the Dolt server version supports DOLT_CONFLICTS_RESOLVE with '--theirs' and a table argument; upgrade dolt if the procedure signature changed.
- Inspect the wrapped inner error (%w) for the underlying SQL error — it names the real cause (unknown procedure, no conflicts, lock timeout).
- Ensure no other process concurrently operates on the same database during merge settlement; serialize SettleMerge calls.
Example fix
// before
if _, err := db.ExecContext(ctx, "CALL DOLT_CONFLICTS_RESOLVE('--theirs', '"+table+"')"); err != nil {
return false, fmt.Errorf("failed to resolve %s conflicts: %w", table, err)
}
// after
var hasConflicts int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts WHERE `table` = ?", table).Scan(&hasConflicts); err != nil || hasConflicts == 0 {
return false, nil // nothing to resolve; skip instead of failing
}
if _, err := db.ExecContext(ctx, "CALL DOLT_CONFLICTS_RESOLVE('--theirs', '"+table+"')"); err != nil {
return false, fmt.Errorf("failed to resolve %s conflicts: %w", table, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
var n int err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts WHERE `table` = ?", table).Scan(&n) // proceed only if err == nil && n > 0 and dolt_status shows an active merge
Type guard
func hasActiveMergeConflicts(ctx context.Context, db DBConn, table string) bool {
var n int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts WHERE `table` = ?", table).Scan(&n); err != nil {
return false
}
return n > 0
} Try / catch
ok, err := TryAutoResolveMergeConflicts(ctx, db)
if err != nil {
var resolveErr *fmt.WrapError // or errors.As on the wrapped driver error
if errors.As(err, &resolveErr) && strings.Contains(err.Error(), "failed to resolve") {
_, _ = db.ExecContext(ctx, "CALL DOLT_MERGE('--abort')") // reset to clean state, then retry SettleMerge
}
return err
} Prevention
- Always call SettleMerge only right after a merge that reported conflicts; never on a clean working set.
- Serialize merge settlement across processes (single writer or lock) to avoid mid-resolve state changes.
- Pin and test against the Dolt server version you deploy; stored-procedure behavior changes between versions.
- Always unwrap and log the inner %w error — it names the actual SQL failure.
When it happens
Trigger: SettleMerge → TryAutoResolveMergeConflicts hits a conflict class that falls into the default branch (not union-resolved) and CALL DOLT_CONFLICTS_RESOLVE('--theirs', '<table>') returns a SQL error, e.g. no conflicts exist for that table, the merge was aborted, or the Dolt procedure rejects the argument.
Common situations: A concurrent process aborted or completed the merge between conflict detection and resolution; a Dolt version where the stored procedure signature changed; corrupted or missing conflict metadata after a crashed merge; calling SettleMerge when the working set is not actually in a conflicted merge state.
Related errors
- iter issues: query: %w
- resolve existing wisps for batch delete: %w
- counting nonlocal frozen rows: %w
- query conflicts for table %s: %w
- clear %s conflict: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/2feaad06745227b6.
Report an issue: GitHub.