gastownhall/beads · error
set dolt_allow_commit_conflicts: %w
Error message
set dolt_allow_commit_conflicts: %w
What it means
MergeAndSettleWithStrategy first sets the session variable @@dolt_allow_commit_conflicts=1 so a conflicted merge lands in the working set instead of rolling back. "set dolt_allow_commit_conflicts: %w" wraps the failure of that SET statement. It means the session could not enable conflict tolerance — typically the server is not Dolt, the variable name is unsupported, or the connection is broken.
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:66
func MergeAndSettle(ctx context.Context, db DBConn, ref string) error {
return MergeAndSettleWithStrategy(ctx, db, ref, "")
}
// MergeAndSettleWithStrategy is MergeAndSettle with an operator escape hatch
// (#4992 part 2): a conflict TryAutoResolveMergeConflicts declines is, when
// strategy is non-empty, resolved with strategy ("ours" or "theirs") instead
// of aborting the merge for the operator. strategy == "" is exactly
// MergeAndSettle's behavior (a declined conflict aborts with
// MergeConflictsError). Used by the embedded pull path's `--strategy` flag;
// see SettleMerge for the resolution logic.
func MergeAndSettleWithStrategy(ctx context.Context, db DBConn, ref, strategy string) error {
// Capture pre-merge cleanliness before anything runs: abortMerge's
// hard-reset fallback is only safe when nothing uncommitted predates
// the merge (bd-578h9.2).
preMergeClean := workingSetClean(ctx, db)
if _, err := db.ExecContext(ctx, "SET @@dolt_allow_commit_conflicts = 1"); err != nil {
return fmt.Errorf("set dolt_allow_commit_conflicts: %w", err)
}
if _, err := db.ExecContext(ctx, "SET @@dolt_force_transaction_commit = 1"); err != nil {
return fmt.Errorf("set dolt_force_transaction_commit: %w", err)
}
_, mergeErr := db.ExecContext(ctx, "CALL DOLT_MERGE(?)", ref)
if mergeErr != nil && strings.Contains(mergeErr.Error(), "up to date") {
// DOLT_PULL swallows "Already up to date." internally; we do the same.
mergeErr = nil
}
return SettleMerge(ctx, db, mergeErr, preMergeClean, strategy)
}
// MergeConflictsError reports the conflicts a settle pass refused to
// auto-resolve. By the time the caller sees it the merge has been aborted (or
// the transaction rolled back) and the working set restored, so the conflicts
// are no longer queryable from dolt_conflicts — they were captured before the
// abort precisely so callers with a conflict-reporting contract (PullFrom) canView on GitHub (pinned to 71377f2769)
Solutions
- Verify the backend is Dolt and recent enough to support @@dolt_allow_commit_conflicts (try `SET @@dolt_allow_commit_conflicts = 1` manually)
- Check the connection/session is alive and pinned (single session, not rotating pool connections)
- Inspect the wrapped driver error to distinguish unknown-variable from connection errors
- Upgrade the Dolt engine/server if the variable is unrecognized
Example fix
// before: opaque SET failure on unknown backend
err := versioncontrolops.MergeAndSettle(ctx, db, ref)
// after: pre-flight capability check
if _, err := db.ExecContext(ctx, "SET @@dolt_allow_commit_conflicts = 1"); err != nil {
return fmt.Errorf("backend does not support dolt_allow_commit_conflicts (is this Dolt?): %w", err)
}
err = versioncontrolops.MergeAndSettle(ctx, db, ref) Defensive patterns
Strategy: try-catch
Validate before calling
// capability pre-flight on the same session used for the merge
if _, err := db.ExecContext(ctx, "SET @@dolt_allow_commit_conflicts = 1"); err != nil {
return fmt.Errorf("backend lacks conflict-tolerant merge (Dolt required): %w", err)
} Type guard
func isUnknownVariable(err error) bool { return strings.Contains(err.Error(), "Unknown system variable") || strings.Contains(err.Error(), "1193") } Try / catch
err := versioncontrolops.MergeAndSettle(ctx, db, ref)
if err != nil {
if isUnknownVariable(err) {
return fmt.Errorf("Dolt version too old for auto-settle merge: %w", err)
}
return fmt.Errorf("merge settle failed: %w", err)
} Prevention
- Pin the minimum Dolt engine version required by bd
- Use one pinned session for the whole merge-settle sequence
- Health-check session variables at startup
- Reconnect and retry once on transient connection errors
When it happens
Trigger: Calling MergeAndSettle/MergeAndSettleWithStrategy against a non-Dolt MySQL server or a Dolt version lacking dolt_allow_commit_conflicts; a closed or broken connection; context cancellation before the SET executes.
Common situations: Running embedded-mode pull against a downgraded/older Dolt engine; pointing the pull path at a plain MySQL replica; connection dropped by a proxy between commands.
Related errors
- set dolt_force_transaction_commit: %w
- failed to commit pending changes before pull: %w
- merge failed: %w
- pull merge left constraint violations bd cannot auto-repair;
- merge succeeded but is_blocked recompute failed: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e30e3eeb4b4bd5a6.
Report an issue: GitHub.