gastownhall/beads · error

conflicts resolved with '%s' strategy but merge left constra

Error message

conflicts resolved with '%s' strategy but merge left constraint violations bd cannot auto-repair; inspect dolt_constraint_violations and resolve before retrying

What it means

The chosen strategy (ours/theirs) resolved the conflicts, but Dolt still reports rows in dolt_constraint_violations that bd's automatic FK-cascade repair could not fix. Rather than commit a violating working set, the library aborts the merge and asks the user to inspect and resolve violations manually.

Source

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

			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)
	}

	if err := StageAndCommit(ctx, db, dirtyTables,
		fmt.Sprintf("Resolve merge conflicts from %s using %s strategy", ref, strategy), author); err != nil {
		abortMerge(ctx, db, preMergeClean)
		return conflicts, fmt.Errorf("conflicts resolved but commit failed: %w", err)
	}

	return conflicts, nil
}

// abortMerge restores the pre-merge state after a settle pass refused the
// merge — the autocommit-mode stand-in for server mode's tx.Rollback().
// DOLT_MERGE('--abort') is the precise tool but only works while merge state
// is active; a force-committed violation-only merge may have closed it, so
// fall back to a hard reset — but only when the working set was clean before
// the merge ran. The most common reason --abort fails is a merge that
// REFUSED TO START on a dirty working set; hard-resetting there would

View on GitHub (pinned to 71377f2769)

Solutions

  1. Query `SELECT * FROM dolt_constraint_violations` (and its per-table variants) to see the violating rows
  2. Delete or fix the violating rows (e.g. remove orphaned dependents or restore the missing parent), then re-run the merge
  3. Prefer a strategy or pre-merge cleanup that removes dependents of deleted issues before merging
  4. If violations persist as a library bug, file with the specific rows from dolt_constraint_violations

Example fix

// inspect and clean
rows := query("SELECT `table`, id FROM dolt_constraint_violations")
// delete orphaned dependents, e.g.:
db.Exec("DELETE FROM issue_labels WHERE issue_id NOT IN (SELECT id FROM issues)")
// then retry the merge
Defensive patterns

Strategy: fallback

Validate before calling

rows, _ := db.QueryContext(ctx, "SELECT \"table\", id FROM dolt_constraint_violations")
// if non-empty before merge, clean up first

Try / catch

_, err := MergeWithStrategy(ctx, db, ref, "ours", author)
if err != nil && strings.Contains(err.Error(), "constraint violations") {
    // manual remediation:
    // DELETE orphaned dependents or restore missing parents,
    // verify dolt_constraint_violations is empty, then retry merge
}

Prevention

When it happens

Trigger: After strategy resolution, a constraint-violation check finds violations (had=true) but the auto-repair pass repairs none or not all (repaired=false) — typically FK cascade violations left by --ours/--theirs resolution (bd-6dnrw.4 / #4992).

Common situations: Merging branches where one side deleted a parent row (issue) the other side still references (dependent row), and the strategy kept both sides inconsistently.

Related errors


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