{"record":{"id":"0de94fa5d4c0f3cd","repo":"gastownhall/beads","slug":"conflict-resolution-failed-for-s-w-0de94f","errorCode":null,"errorMessage":"conflict resolution failed for %s: %w","messagePattern":"conflict resolution failed for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/embeddeddolt/federation.go","lineNumber":338,"sourceCode":"\tremoteBranch := fmt.Sprintf(\"%s/%s\", peer, s.branch)\n\tconflicts, err := s.Merge(ctx, remoteBranch)\n\tif err != nil {\n\t\tresult.Error = fmt.Errorf(\"merge failed: %w\", err)\n\t\treturn result, result.Error\n\t}\n\n\t// Step 4: Handle conflicts\n\tif len(conflicts) > 0 {\n\t\tresult.Conflicts = conflicts\n\n\t\tif strategy == \"\" {\n\t\t\tresult.Error = fmt.Errorf(\"merge conflicts require resolution (use --strategy ours|theirs)\")\n\t\t\treturn result, result.Error\n\t\t}\n\n\t\tfor _, c := range conflicts {\n\t\t\tif err := s.ResolveConflicts(ctx, c.Field, strategy); err != nil {\n\t\t\t\tresult.Error = fmt.Errorf(\"conflict resolution failed for %s: %w\", c.Field, err)\n\t\t\t\treturn result, result.Error\n\t\t\t}\n\t\t}\n\t\tresult.ConflictsResolved = true\n\n\t\t// CommitMergeResolution, not Commit: Commit's GH#3886 nothing-to-commit\n\t\t// tolerance would swallow the --ours case (resolution dirties nothing)\n\t\t// as a silent no-op here, leaving dolt_merge_status.is_merging true while\n\t\t// this function reports result.Merged = true and pushes — the exact\n\t\t// re-wedge CommitMergeResolution's doc comment describes. See the\n\t\t// server-mode twin, dolt/federation.go's Sync.\n\t\tif err := s.CommitMergeResolution(ctx, fmt.Sprintf(\"Resolve conflicts from %s using %s strategy\", peer, strategy)); err != nil {\n\t\t\tresult.Error = fmt.Errorf(\"commit conflict resolution: %w\", err)\n\t\t\treturn result, result.Error\n\t\t}\n\n\t\t// bd-578h9.11: the conflicted merge skipped the automatic is_blocked\n\t\t// recompute (unresolved rows would have fed it garbage); now that the","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/embeddeddolt/federation.go#L320-L356","documentation":"After conflicts are detected and a strategy was given, Sync resolves each conflicting field via s.ResolveConflicts(ctx, c.Field, strategy). If resolution of any field fails, the error is wrapped with the offending field name, aborting the sync with the merge still in a conflicted state.","triggerScenarios":"store.Sync(ctx, peer, strategy) where ResolveConflicts errors for a specific c.Field: the field key is unknown to the conflict resolver, the underlying SQL update against dolt_conflicts fails, or the merge state changed concurrently.","commonSituations":"Schema drift between peers introduced a field the resolver doesn't know; a concurrent process aborted the merge mid-resolution; storage error while writing the resolved value.","solutions":["Check the named field in the error — verify both peers have compatible schemas for it.","Re-run sync with the strategy; resolution is retryable per field.","Inspect dolt conflicts tables to see the row-level conflict and resolve manually if needed.","Abort the in-progress merge (dolt merge --abort equivalent) and re-sync from a clean state."],"exampleFix":"// before: unknown field fails resolution\nfor _, c := range conflicts {\n    if err := s.ResolveConflicts(ctx, c.Field, strategy); err != nil { ... }\n}\n// after: skip/log fields the resolver cannot handle, resolve the rest\nfor _, c := range conflicts {\n    if !isResolvableField(c.Field) {\n        log.Printf(\"manual resolution needed for %s\", c.Field)\n        continue\n    }\n    if err := s.ResolveConflicts(ctx, c.Field, strategy); err != nil { ... }\n}","handlingStrategy":"try-catch","validationCode":"// verify schemas are compatible before cross-peer sync\nif err := schemaCompatible(localSchema(), peerSchema(peer)); err != nil {\n    return fmt.Errorf(\"skip sync: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"result, err := store.Sync(ctx, peer, \"ours\")\nif err != nil && strings.Contains(err.Error(), \"conflict resolution failed for \") {\n    field := extractField(err.Error())\n    log.Printf(\"manual resolution needed for field %q from peer %s\", field, peer)\n    abortMergeIfNeeded(ctx, store)\n}","preventionTips":["Keep peer schemas in lockstep before enabling federation.","Retry sync after transient resolution failures — it is per-field retryable.","Abort in-progress merges before starting a new sync.","Log every conflict field for post-hoc review."],"tags":["merge-conflict","resolution","sync"],"backgroundTag":"merge-conflict-resolution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}