gastownhall/beads · error

conflicts resolved but commit failed: %w

Error message

conflicts resolved but commit failed: %w

What it means

In SettleMerge's strategy path, after conflicts are resolved with the operator's strategy, the settle concludes with `CALL DOLT_COMMIT('-m', ...)`. "conflicts resolved but commit failed: %w" wraps that commit's failure. The merge is aborted and the working set restored, so the resolution is not persisted — the pull must be retried after fixing the commit failure.

Source

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

	// DOLT_COMMIT refuses a violated working set, so a merge carrying both
	// classes could never settle when the resolver committed first (bd-578h9.14).
	switch {
	case resolved:
		if err := CommitResolvedConflicts(ctx, db); err != nil {
			abortMerge(ctx, db, preMergeClean)
			if mergeErr != nil {
				return mergeErr
			}
			return err
		}
	case strategyResolved:
		msg := fmt.Sprintf("Resolve merge conflicts using '%s' strategy", strategy)
		if _, err := db.ExecContext(ctx, "CALL DOLT_COMMIT('-m', ?)", msg); err != nil {
			abortMerge(ctx, db, preMergeClean)
			if mergeErr != nil {
				return mergeErr
			}
			return fmt.Errorf("conflicts resolved but commit failed: %w", err)
		}
	}

	return nil
}

// MergeWithStrategy merges ref into the current branch and, when the merge
// produces conflicts, resolves EVERY conflicted table with the operator's
// explicit strategy ("ours" or "theirs") instead of aborting for later
// resolution. It backs `bd vc merge --strategy` (#4992): the flag existed
// and was documented, but the merge ran as a bare `CALL DOLT_MERGE` inside an
// implicit autocommit transaction, so Dolt rejected any real conflict with
// Error 1105 ("@autocommit must be disabled ...") before the strategy could
// ever be applied — the strategy path was dead code.
//
// Unlike TryAutoResolveMergeConflicts (which only resolves conflict classes
// proven safe without operator input, e.g. GH#2466 metadata), no allowlist
// applies here: the operator named the strategy, so every conflicted table is

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the pull after confirming no other session is using the database — the abort restored a clean state
  2. Inspect the wrapped error: constraint-violation refusals mean resolve the remaining violations first (see dolt_constraint_violations)
  3. Ensure the merge actually left repairable violations; run bd doctor to check schema consistency
  4. Upgrade Dolt/bd if DOLT_COMMIT's argument handling differs in your version
Defensive patterns

Strategy: retry

Validate before calling

// after a failed strategy commit, verify no residual violations before retrying
rows, err := db.QueryContext(ctx, "SELECT `table` FROM dolt_constraint_violations WHERE num_violations > 0")
// if rows exist, repair them before re-running the merge

Type guard

func isCommitAfterResolveFailure(err error) bool {
	return strings.Contains(err.Error(), "conflicts resolved but commit failed")
}

Try / catch

err := versioncontrolops.MergeAndSettleWithStrategy(ctx, db, ref, strategy)
if err != nil && isCommitAfterResolveFailure(err) {
	time.Sleep(500 * time.Millisecond) // merge state was aborted; brief settle
	err = versioncontrolops.MergeAndSettleWithStrategy(ctx, db, ref, strategy)
}

Prevention

When it happens

Trigger: DOLT_COMMIT refusing because the working set still violates constraints (FK repair was skipped or incomplete), no identity for the commit, the merge state having been closed, or a Dolt server error during commit.

Common situations: A merge carrying both resolvable conflicts and unrepairable FK violations in an ordering edge case; Dolt versions where DOLT_COMMIT requires additional flags; concurrent sessions invalidating the merge state between resolve and commit.

Related errors


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