gastownhall/beads · error
resolve %s conflicts with '%s' strategy: %w
Error message
resolve %s conflicts with '%s' strategy: %w
What it means
In SettleMerge's operator escape-hatch path (--strategy ours|theirs), each conflicted table is resolved via ResolveConflicts. "resolve %s conflicts with '%s' strategy: %w" wraps a per-table resolution failure. The merge is aborted and the working set restored before this error is returned, so nothing is left half-resolved.
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:167
if !resolved {
if conflicts, err := GetConflicts(ctx, db); err == nil && len(conflicts) > 0 {
if strategy == "" {
abortMerge(ctx, db, preMergeClean)
return &MergeConflictsError{Conflicts: conflicts, MergeErr: mergeErr}
}
// #4992 part 2: the operator asked for an escape hatch. Unlike
// TryAutoResolveMergeConflicts, no allowlist applies — every
// conflicted table (the resolver pre-screens ALL of them before
// resolving any, so `resolved == false` means none were touched)
// is resolved with the named strategy.
for _, c := range conflicts {
table := c.Field
if table == "" {
table = "issues"
}
if err := ResolveConflicts(ctx, db, table, strategy); err != nil {
abortMerge(ctx, db, preMergeClean)
return fmt.Errorf("resolve %s conflicts with '%s' strategy: %w", table, strategy, err)
}
if _, err := db.ExecContext(ctx, "CALL DOLT_ADD(?)", table); err != nil {
abortMerge(ctx, db, preMergeClean)
return fmt.Errorf("stage resolved %s: %w", table, err)
}
}
strategyResolved = true
}
}
// bd-6dnrw.4: repair FK cascade violations the merge produced (child rows
// whose parent issue was deleted on the other clone). Unrepaired
// violations MUST NOT survive: with the force flag on, every statement
// autocommits, so the abort below is what keeps them out of the database.
// This also covers violations a strategy resolution left behind (e.g.
// --ours keeps a child row whose parent was deleted on the other side).
repairedViol, hadViol, violErr := TryRepairFKCascadeViolations(ctx, db)
if violErr != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Validate the strategy with ValidateConflictStrategy("ours"|"theirs") before calling
- Re-run the merge: the abort restored the working set, so a retry with a corrected strategy is safe
- Check for concurrent sessions touching the same database during the merge
- Inspect the wrapped error for the specific DOLT_CONFLICTS_RESOLVE failure reason
Example fix
// before: unvalidated strategy reaches resolution
err := versioncontrolops.MergeAndSettleWithStrategy(ctx, db, ref, "mine")
// after
if err := versioncontrolops.ValidateConflictStrategy("theirs"); err != nil {
return err
}
err = versioncontrolops.MergeAndSettleWithStrategy(ctx, db, ref, "theirs") Defensive patterns
Strategy: validation
Validate before calling
// validate before calling MergeAndSettleWithStrategy
if strategy != "" && strategy != "ours" && strategy != "theirs" {
return fmt.Errorf("strategy must be ours or theirs, got %q", strategy)
}
// or use the library's validator:
if err := versioncontrolops.ValidateConflictStrategy(strategy); err != nil { return err } Type guard
func validStrategy(s string) bool { return s == "" || s == "ours" || s == "theirs" } Try / catch
err := versioncontrolops.MergeAndSettleWithStrategy(ctx, db, ref, strategy)
if err != nil {
var mce *versioncontrolops.MergeConflictsError
if errors.As(err, &mce) {
// conflicts need operator attention; merge was aborted
} else if strings.Contains(err.Error(), "with '") {
// strategy resolution failed; retry after fixing strategy/session
}
return err
} Prevention
- Always route user-supplied strategy strings through ValidateConflictStrategy
- Avoid concurrent bd sessions during pull/merge
- Retry once after a resolution failure — the abort restores the working set
- Keep Dolt versions aligned across federation clones
When it happens
Trigger: Calling MergeAndSettleWithStrategy (or MergeAndSettle via MergeAndSettle → WithStrategy "") with a strategy whose resolution fails for a given table — e.g. an invalid strategy string reaching ResolveConflicts, or Dolt rejecting DOLT_CONFLICTS_RESOLVE because the conflict set changed mid-loop.
Common situations: Passing an unvalidated strategy (not validated in this path — validate with ValidateConflictStrategy first); another session resolving the same conflicts concurrently; Dolt version quirks in DOLT_CONFLICTS_RESOLVE argument handling.
Related errors
- failed to get conflicts: %w
- failed to scan conflict: %w
- query conflicts for table %s: %w
- conflict columns for table %s: %w
- scan conflict row for table %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f695b036b9230ab9.
Report an issue: GitHub.