gastownhall/beads · error

merge branch %s: %w

Error message

merge branch %s: %w

What it means

MergeWithStrategy ran CALL DOLT_MERGE and got a non-conflict error (mergeErr), and while inspecting, GetConflicts also failed (cErr). Since the code cannot tell whether the merge failed due to conflicts, it aborts the merge and surfaces the original merge error wrapped as `merge branch %s`.

Source

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

	}
	if _, err := db.ExecContext(ctx, "SET @@dolt_force_transaction_commit = 1"); err != nil {
		return nil, fmt.Errorf("set dolt_force_transaction_commit: %w", err)
	}

	_, mergeErr := db.ExecContext(ctx, "CALL DOLT_MERGE('--author', ?, ?)", author, ref)
	if mergeErr != nil && strings.Contains(mergeErr.Error(), "up to date") {
		mergeErr = nil
	}

	// Check for conflicts regardless of whether the merge statement itself
	// errored: with the flags above set, a genuinely conflicted merge lands in
	// the working set instead of erroring, but older Dolt behavior (or a
	// conflict class the flags don't cover) may still report both.
	conflicts, cErr := GetConflicts(ctx, db)
	if cErr != nil {
		abortMerge(ctx, db, preMergeClean)
		if mergeErr != nil {
			return nil, fmt.Errorf("merge branch %s: %w", ref, mergeErr)
		}
		return nil, fmt.Errorf("check merge conflicts for branch %s: %w", ref, cErr)
	}

	if len(conflicts) == 0 {
		if mergeErr != nil {
			// Not a conflict: some other merge failure (unknown branch, dirty
			// working set, ...). Nothing to resolve — surface it as-is.
			abortMerge(ctx, db, preMergeClean)
			return nil, fmt.Errorf("merge branch %s: %w", ref, mergeErr)
		}
		return nil, nil
	}

	dirtyTables := make(map[string]bool, len(conflicts))
	for _, c := range conflicts {
		table := c.Field
		if table == "" {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped inner error: if it says 'unknown branch' or similar, verify the ref exists (`DOLT_BRANCHES` or `bd branch list`)
  2. Commit or stash local changes so the working set is clean before merging
  3. Ensure the Dolt version exposes dolt_conflicts; upgrade if the table query fails
  4. Retry the merge once the underlying cause from the inner error is fixed

Example fix

// before
MergeWithStrategy(ctx, db, "feat/reopsitory-fix", ...) // typo'd ref
// after
MergeWithStrategy(ctx, db, "feat/repository-fix", ...)
Defensive patterns

Strategy: try-catch

Validate before calling

var n int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_branches WHERE name = ?", ref).Scan(&n); err != nil || n == 0 {
    return fmt.Errorf("branch %q does not exist", ref)
}

Try / catch

conflicts, err := MergeWithStrategy(ctx, db, ref, strategy, author)
if err != nil {
    if strings.Contains(err.Error(), "unknown") || strings.Contains(err.Error(), "not found") {
        // bad ref: verify branch name
    } else if strings.Contains(err.Error(), "working set") || strings.Contains(err.Error(), "dirty") {
        // commit/stash first, then retry once
    }
}

Prevention

When it happens

Trigger: DOLT_MERGE fails (e.g. unknown branch ref, dirty working set, refspec error) AND the follow-up `SELECT ... FROM dolt_conflicts` query inside GetConflicts also errors, so the conflict-vs-hard-failure distinction cannot be made.

Common situations: Merging a ref that does not exist (typo in branch name); working set dirty so DOLT_MERGE refuses; the dolt_conflicts system table missing/unavailable on an old server, compounding the original failure.

Related errors


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