gastownhall/beads · error
failed to commit resolved conflicts: %w
Error message
failed to commit resolved conflicts: %w
What it means
CommitResolvedConflicts runs CALL DOLT_COMMIT('-m', ...) to commit the working set after all merge conflicts were auto-resolved. DOLT_COMMIT refuses a working set with outstanding constraint violations (e.g. FK cascade violations, per bd-578h9.14), so the commit fails and the merge cannot settle even though conflict resolution itself succeeded.
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:581
//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).
func CommitResolvedConflicts(ctx context.Context, db DBConn) error {
if _, err := db.ExecContext(ctx, "CALL DOLT_COMMIT('-m', 'auto-resolve merge conflicts: metadata, dependencies, schema_migrations, config, issues (field-level three-way merge), labels/comments/events (union)')"); err != nil {
return fmt.Errorf("failed to commit resolved conflicts: %w", err)
}
return nil
}
// dependencyConflictsAreAuditOnly reports whether every conflicted row in the
// dependencies table is the SAME logical edge on both sides that differs only in
// audit columns (created_at/created_by/metadata/thread_id) — the only class safe to
// auto-resolve with --theirs.
//
// It does NOT trust the primary key as proof of a shared edge. With deterministic
// ids the same edge has the same id on every clone, but an issue rename can leave a
// row's surrogate id stale (depid.New(oldID, target)) while issue_id/target have
// already moved (#4259 finding 2), so two genuinely different edges could collide on
// one id. We therefore verify the natural identity — issue_id and the resolved
// target — matches on both sides, and that the type matches, before declaring the
// conflict audit-only. It returns false if any conflicted row differs in identity or
// type, or was deleted on one side (an add/delete conflict).
func dependencyConflictsAreAuditOnly(ctx context.Context, db DBConn) (bool, error) {View on GitHub (pinned to 71377f2769)
Solutions
- Check dolt_status for remaining conflicts — any un-resolved table blocks DOLT_COMMIT; resolve or abort them first.
- Inspect constraint/FK violations in the resolved tables; delete or repair dangling rows (e.g. orphaned dependencies) before committing.
- If the merge cannot be settled automatically, abort (CALL DOLT_MERGE('--abort')) and re-merge after fixing the source data.
- Ensure CommitResolvedConflicts runs only after ALL resolvers finished, including constraint-violation cleanup, not just conflict resolution.
Example fix
// before
func CommitResolvedConflicts(ctx context.Context, db DBConn) error {
if _, err := db.ExecContext(ctx, "CALL DOLT_COMMIT('-m', 'auto-resolve merge conflicts: ...')"); err != nil {
return fmt.Errorf("failed to commit resolved conflicts: %w", err)
}
return nil
}
// after
func CommitResolvedConflicts(ctx context.Context, db DBConn) error {
var remaining int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts").Scan(&remaining); err == nil && remaining > 0 {
return fmt.Errorf("cannot commit: %d tables still have unresolved conflicts", remaining)
}
if _, err := db.ExecContext(ctx, "CALL DOLT_COMMIT('-m', 'auto-resolve merge conflicts: ...')"); err != nil {
return fmt.Errorf("failed to commit resolved conflicts: %w", err)
}
return nil
} Defensive patterns
Strategy: validation
Validate before calling
var remainingConflicts, fkViolations int db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts").Scan(&remainingConflicts) db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dependencies d LEFT JOIN issues i ON d.depends_on_issue_id = i.id WHERE d.depends_on_issue_id IS NOT NULL AND i.id IS NULL").Scan(&fkViolations) // only call CommitResolvedConflicts when both are 0
Type guard
func workingSetCommitReady(ctx context.Context, db DBConn) bool {
var conflicts int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_conflicts").Scan(&conflicts); err != nil || conflicts > 0 {
return false
}
return true
} Try / catch
if err := CommitResolvedConflicts(ctx, db); err != nil {
// constraint violation suspected: inspect dangling rows, clean them, retry commit
var dangling int
db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dependencies d LEFT JOIN issues i ON d.depends_on_issue_id = i.id WHERE i.id IS NULL AND d.depends_on_issue_id IS NOT NULL").Scan(&dangling)
if dangling > 0 {
db.ExecContext(ctx, "DELETE FROM dependencies WHERE depends_on_issue_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM issues WHERE id = depends_on_issue_id)")
err = CommitResolvedConflicts(ctx, db) // retry once
}
} Prevention
- Run all resolvers (conflicts AND constraint-violation cleanup) before committing — the bd-578h9.14 ordering bug.
- Before merging, validate referential integrity so '--theirs' resolution cannot restore dangling rows.
- After auto-resolve, always check dolt_conflicts is empty before DOLT_COMMIT.
- On failure, abort the merge rather than leaving a half-resolved working set.
When it happens
Trigger: SettleMerge → CommitResolvedConflicts calls DOLT_COMMIT while the resolved working set still violates constraints — most commonly foreign-key cascade violations in tables that were force-resolved with '--theirs', or unresolved conflicts remaining in a table not covered by the auto-resolver.
Common situations: A merge carries both an auto-resolvable conflict and an FK violation in another table (the exact bd-578h9.14 scenario); '--theirs' resolution restored rows whose references were deleted on our side; dangling dependency rows referencing issues deleted by the merge.
Related errors
- pull merge left constraint violations bd cannot auto-repair;
- conflicts resolved but commit failed: %w
- failed to commit restore: %w
- commit import: %w
- failed to commit is_blocked repairs to Dolt: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e51fe45c8306b359.
Report an issue: GitHub.