gastownhall/beads · error

merge failed: %w

Error message

merge failed: %w

What it means

After a successful fetch, Sync merges the peer's branch (<peer>/<branch>). Any error from s.Merge(ctx, remoteBranch) is wrapped as 'merge failed', aborting before conflict handling. This is a hard merge failure, not a conflict outcome.

Source

Thrown at internal/storage/embeddeddolt/federation.go:323

		result.Error = fmt.Errorf("commit pending before sync: %w", err)
		return result, result.Error
	}

	// Step 1: Fetch
	if err := s.Fetch(ctx, peer); err != nil {
		result.Error = fmt.Errorf("fetch failed: %w", err)
		return result, result.Error
	}
	result.Fetched = true

	// Step 2: Get commit before merge for change detection
	beforeCommit, _ := s.GetCurrentCommit(ctx)

	// Step 3: Merge peer's branch
	remoteBranch := fmt.Sprintf("%s/%s", peer, s.branch)
	conflicts, err := s.Merge(ctx, remoteBranch)
	if err != nil {
		result.Error = fmt.Errorf("merge failed: %w", err)
		return result, result.Error
	}

	// Step 4: Handle conflicts
	if len(conflicts) > 0 {
		result.Conflicts = conflicts

		if strategy == "" {
			result.Error = fmt.Errorf("merge conflicts require resolution (use --strategy ours|theirs)")
			return result, result.Error
		}

		for _, c := range conflicts {
			if err := s.ResolveConflicts(ctx, c.Field, strategy); err != nil {
				result.Error = fmt.Errorf("conflict resolution failed for %s: %w", c.Field, err)
				return result, result.Error
			}
		}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-run sync after a fresh fetch to rule out a corrupted transfer.
  2. If histories diverged (force-push), decide on one side: reset to a common ancestor or recreate the peer branch.
  3. Inspect dolt_merge_status and merge logs for the concrete underlying error.
  4. Use explicit strategy resolution (--strategy ours|theirs) if the failure is conflict-related underneath.

Example fix

// before: force-pushed peer -> unrelated histories -> merge failed
result, err := store.Sync(ctx, peer)
// after: verify shared history before merging
if !historiesShareAncestor(localCommit, peerCommit) {
    return fmt.Errorf("peer %s rewrote history; reconcile branches first", peer)
}
result, err = store.Sync(ctx, peer)
Defensive patterns

Strategy: try-catch

Try / catch

result, err := store.Sync(ctx, peer)
if err != nil && strings.Contains(err.Error(), "merge failed") {
    // surface underlying dolt_merge_status detail and stop automerge
    log.Printf("merge with %s failed; manual reconciliation required: %v", peer, err)
    disableAutomerge(peer)
}

Prevention

When it happens

Trigger: store.Sync(ctx, peer) where s.Merge errors on merging remoteBranch: Dolt merge engine failure, divergent histories that Dolt cannot merge, corrupt objects fetched from the peer, or an internal dolt_schemas conflict.

Common situations: Peers rewrote history (force-push) making histories unrelated; fetched refs corrupted over an unreliable transport; storage-level failure during merge.

Related errors


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