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

  1. Validate the strategy with ValidateConflictStrategy("ours"|"theirs") before calling
  2. Re-run the merge: the abort restored the working set, so a retry with a corrected strategy is safe
  3. Check for concurrent sessions touching the same database during the merge
  4. 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

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


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