gastownhall/beads · error

failed to resolve config conflicts: %w

Error message

failed to resolve config conflicts: %w

What it means

For conflicts in the `config` table, the auto-resolver takes the remote value (--theirs) and issues CALL DOLT_CONFLICTS_RESOLVE('--theirs', 'config'). If that call errors, the auto-resolve aborts with this wrapped error and the caller (SettleMerge) falls back or fails.

Source

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

			// Row-wise: keep whichever side recorded a content hash, so the
			// table-level --ours/--theirs choice can never drop one.
			if err := resolveSchemaMigrationsVintageConflicts(ctx, db); err != nil {
				return false, err
			}
		case "config":
			// --theirs makes this clone's local kv.memory.* edit lose to the
			// remote value (the same convergent trade-off metadata makes). That
			// supersession is otherwise undiagnosable, so name the resolved keys
			// first. Best-effort: a diagnostics query failure must not abort an
			// otherwise-correct resolution.
			if keys, kerr := resolvedConfigConflictKeys(ctx, db); kerr == nil && len(keys) > 0 {
				fmt.Fprintf(os.Stderr,
					"Notice: auto-resolved %d memory config conflict(s) with the remote value (--theirs); "+
						"local edits to %s were superseded\n",
					len(keys), strings.Join(keys, ", "))
			}
			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)
			}
		}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the inner Dolt error for the precise reason
  2. Run `CALL DOLT_CONFLICTS_RESOLVE('--theirs', 'config')` manually to reproduce
  3. Upgrade Dolt if the call mode is unsupported
  4. If no merge is active, re-run the merge so conflicts exist before settling
Defensive patterns

Strategy: try-catch

Validate before calling

var n int
_ = db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts WHERE \"table\" = 'config'").Scan(&n)
// n > 0 means the --theirs resolve path will be attempted

Try / catch

ok, err := TryAutoResolveMergeConflicts(ctx, db)
if err != nil && strings.Contains(err.Error(), "config conflicts") {
    // manual fallback:
    _, _ = db.ExecContext(ctx, "CALL DOLT_CONFLICTS_RESOLVE('--theirs', 'config')")
    // or resolve per-key manually, preserving local overrides deliberately
}

Prevention

When it happens

Trigger: Config-table conflicts exist after a merge, but DOLT_CONFLICTS_RESOLVE('--theirs','config') is rejected — unsupported resolution mode, table name mismatch, or no active merge in the session.

Common situations: Both local and remote edited a config key (e.g. remote URL, default branch); local edits get superseded by design but the resolve call itself fails on older Dolt or a mid-merge session mismatch.

Related errors


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