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 wouldView on GitHub (pinned to 71377f2769)
Solutions
- Query `SELECT * FROM dolt_constraint_violations` (and its per-table variants) to see the violating rows
- Delete or fix the violating rows (e.g. remove orphaned dependents or restore the missing parent), then re-run the merge
- Prefer a strategy or pre-merge cleanup that removes dependents of deleted issues before merging
- 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
- Run FK-integrity cleanup (remove dependents of deleted issues) before merging
- Prefer strategies that keep referential consistency for parent tables
- Monitor dolt_constraint_violations after every strategy-resolved merge
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
- pull merge left constraint violations bd cannot auto-repair;
- failed to commit pending changes before pull: %w
- merge failed: %w
- merge succeeded but is_blocked recompute failed: %w
- acquire connection for merge: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/968731596a610c51.
Report an issue: GitHub.