{"record":{"id":"8e6fb47cd04148fc","repo":"gastownhall/beads","slug":"commit-conflict-resolution-w","errorCode":null,"errorMessage":"commit conflict resolution: %w","messagePattern":"commit conflict resolution: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/embeddeddolt/federation.go","lineNumber":351,"sourceCode":"\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\n\t\t// resolution is committed, cover the whole merge+resolution window.\n\t\tif err := s.RecomputeBlockedAfterMerge(ctx, beforeCommit); err != nil {\n\t\t\tresult.Error = fmt.Errorf(\"conflicts resolved but is_blocked recompute failed: %w\", err)\n\t\t\treturn result, result.Error\n\t\t}\n\t}\n\tresult.Merged = true\n\n\tafterCommit, _ := s.GetCurrentCommit(ctx)\n\tif beforeCommit != afterCommit {\n\t\tresult.PulledCommits = 1\n\t}\n","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/embeddeddolt/federation.go#L333-L369","documentation":"After all conflicts are resolved, Sync commits the resolution via CommitMergeResolution (not Commit — plain Commit's nothing-to-commit tolerance would silently skip the --ours case where resolution dirties nothing, leaving dolt_merge_status.is_merging true while sync reports Merged=true and pushes). Any failure from that commit is wrapped as 'commit conflict resolution'.","triggerScenarios":"store.Sync(ctx, peer, strategy) where CommitMergeResolution(ctx, \"Resolve conflicts from <peer> using <strategy> strategy\") errors: DOLT_COMMIT fails on the resolution working set, stale merge state, lock files, or I/O failure.","commonSituations":"Stale is_merging state from a previous wedged sync; disk full during the resolution commit; concurrent process touched the working set between resolution and commit.","solutions":["Check dolt_merge_status — if is_merging is stuck, clear/abort the merge and re-run sync.","Remove stale dolt lock files left by crashed processes, then retry.","Free disk space / fix filesystem permissions on the data directory.","Re-run the whole sync with the same strategy; resolution+commit is idempotent from a clean merge state."],"exampleFix":"// before: wedged is_merging blocks the resolution commit\nif err := s.CommitMergeResolution(ctx, msg); err != nil { ... }\n// after: verify merge state is clean before attempting sync\nif merging, _ := s.isMergeInProgress(ctx); merging {\n    return fmt.Errorf(\"previous merge still in progress; resolve or abort first\")\n}\nif err := s.CommitMergeResolution(ctx, msg); err != nil { ... }","handlingStrategy":"try-catch","validationCode":"// refuse to start a new sync while a merge is already in progress\nif merging := mergeInProgress(store, ctx); merging {\n    return fmt.Errorf(\"previous merge still in progress; resolve or abort first\")\n}","typeGuard":null,"tryCatchPattern":"result, err := store.Sync(ctx, peer, strategy)\nif err != nil && strings.Contains(err.Error(), \"commit conflict resolution\") {\n    // clear stuck is_merging state, then retry the full sync\n    if aerr := abortStuckMerge(ctx, store); aerr == nil {\n        result, err = store.Sync(ctx, peer, strategy)\n    }\n}","preventionTips":["Check dolt_merge_status.is_merging before sync runs.","Clean stale lock files after any crashed process.","Never run concurrent syncs against one embedded repo.","Monitor disk space on the data directory."],"tags":["merge-conflict","commit","sync","dolt"],"backgroundTag":"merge-state-wedged","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}