gastownhall/beads · error

resolve %s conflicts: %w

Error message

resolve %s conflicts: %w

What it means

After conflicts were detected, MergeWithStrategy calls ResolveConflicts per conflicted table with the chosen strategy (ours/theirs). If the per-table DOLT_CONFLICTS_RESOLVE call fails, the merge is aborted and this error reports which table could not be resolved.

Source

Thrown at internal/storage/versioncontrolops/mergesettle.go:311

	if len(conflicts) == 0 {
		if mergeErr != nil {
			// Not a conflict: some other merge failure (unknown branch, dirty
			// working set, ...). Nothing to resolve — surface it as-is.
			abortMerge(ctx, db, preMergeClean)
			return nil, fmt.Errorf("merge branch %s: %w", ref, mergeErr)
		}
		return nil, nil
	}

	dirtyTables := make(map[string]bool, len(conflicts))
	for _, c := range conflicts {
		table := c.Field
		if table == "" {
			table = "issues"
		}
		if err := ResolveConflicts(ctx, db, table, strategy); err != nil {
			abortMerge(ctx, db, preMergeClean)
			return conflicts, fmt.Errorf("resolve %s conflicts: %w", table, err)
		}
		dirtyTables[table] = true
	}

	// bd-6dnrw.4 / #4992: a strategy resolution can leave FK cascade
	// violations behind exactly like the auto-resolve path (e.g. --ours keeps
	// a child row whose parent was deleted on the other side); repair them the
	// same way so a strategy-resolved merge cannot silently commit a violated
	// working set.
	repaired, had, violErr := TryRepairFKCascadeViolations(ctx, db)
	if violErr != nil {
		abortMerge(ctx, db, preMergeClean)
		return conflicts, violErr
	}
	if had && !repaired {
		abortMerge(ctx, db, preMergeClean)
		return conflicts, fmt.Errorf("conflicts resolved with '%s' strategy but merge left constraint violations bd cannot auto-repair; inspect dolt_constraint_violations and resolve before retrying", strategy)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped inner error for the exact Dolt message
  2. Run `SELECT * FROM dolt_conflicts` to see which tables actually have conflicts, then resolve manually with CALL DOLT_CONFLICTS_RESOLVE
  3. Ensure only one process settles the merge at a time (lock/serialize merges)
  4. Upgrade Dolt if DOLT_CONFLICTS_RESOLVE is unsupported
Defensive patterns

Strategy: try-catch

Validate before calling

rows, err := db.QueryContext(ctx, "SELECT \"table\" FROM dolt_conflicts")
if err == nil {
    for rows.Next() { /* confirm expected tables have conflicts before settling */ }
    rows.Close()
}

Try / catch

conflicts, err := MergeWithStrategy(ctx, db, ref, strategy, author)
if err != nil && strings.Contains(err.Error(), "resolve ") {
    // per-table resolve failed; fall back to manual
    // CALL DOLT_CONFLICTS_RESOLVE('--ours', '<table>') per conflicted table
}

Prevention

When it happens

Trigger: ResolveConflicts executes `CALL DOLT_CONFLICTS_RESOLVE('--ours'|'--theirs', table)` and Dolt returns an error — e.g. the table no longer has conflicts (already resolved), the table name is wrong, or the server rejects the call.

Common situations: A conflict row whose `table` field is empty mapped to 'issues' but the real conflicts are in another table; concurrent process already resolved the conflicts; Dolt version lacking DOLT_CONFLICTS_RESOLVE for the given mode.

Related errors


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