{"record":{"id":"2feaad06745227b6","repo":"gastownhall/beads","slug":"failed-to-resolve-s-conflicts-w","errorCode":null,"errorMessage":"failed to resolve %s conflicts: %w","messagePattern":"failed to resolve (.+?) conflicts: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/mergesettle.go","lineNumber":560,"sourceCode":"\t\t\t}\n\t\t\tif _, err := db.ExecContext(ctx, \"CALL DOLT_CONFLICTS_RESOLVE('--theirs', 'config')\"); err != nil {\n\t\t\t\treturn false, fmt.Errorf(\"failed to resolve config conflicts: %w\", err)\n\t\t\t}\n\t\tcase \"issues\":\n\t\t\t// Field-level three-way merge, not a table-level --ours/--theirs:\n\t\t\t// a cell only one side changed keeps that side's value and only a\n\t\t\t// genuinely contested cell falls to LWW (automerge.go).\n\t\t\tif err := resolveIssuesFieldMerge(ctx, db, issuesPlan); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\tcase \"labels\", \"comments\", \"events\":\n\t\t\tif err := resolveUnionConflicts(ctx, db, table, unionPlans[table]); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\tdefault:\n\t\t\t//nolint:gosec // G201: table is one of the hardcoded constants above.\n\t\t\tif _, err := db.ExecContext(ctx, \"CALL DOLT_CONFLICTS_RESOLVE('--theirs', '\"+table+\"')\"); err != nil {\n\t\t\t\treturn false, fmt.Errorf(\"failed to resolve %s conflicts: %w\", table, err)\n\t\t\t}\n\t\t}\n\t\t//nolint:gosec // G201: table is one of the hardcoded constants above.\n\t\tif _, err := db.ExecContext(ctx, \"CALL DOLT_ADD('\"+table+\"')\"); err != nil {\n\t\t\treturn false, fmt.Errorf(\"failed to stage %s: %w\", table, err)\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\n// CommitResolvedConflicts creates the dolt commit that concludes a merge whose\n// conflicts TryAutoResolveMergeConflicts settled. Callers that saw\n// resolved=true MUST call this, and only AFTER TryRepairFKCascadeViolations\n// has run: DOLT_COMMIT refuses a working set with outstanding constraint\n// violations, so a merge carrying both an auto-resolvable conflict and an FK\n// cascade violation could never settle while the resolver committed first\n// (bd-578h9.14).","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/mergesettle.go#L542-L578","documentation":"This error wraps a failure from the Dolt stored procedure CALL DOLT_CONFLICTS_RESOLVE('--theirs', table) inside TryAutoResolveMergeConflicts. The routine resolves merge conflicts for a hardcoded bead table by taking the incoming ('--theirs') version of every conflicted row. If the SQL call errors — bad table name, no active conflict state, or a Dolt engine failure — it is wrapped with the table name so the caller knows which table's conflicts could not be resolved.","triggerScenarios":"SettleMerge → TryAutoResolveMergeConflicts hits a conflict class that falls into the default branch (not union-resolved) and CALL DOLT_CONFLICTS_RESOLVE('--theirs', '<table>') returns a SQL error, e.g. no conflicts exist for that table, the merge was aborted, or the Dolt procedure rejects the argument.","commonSituations":"A concurrent process aborted or completed the merge between conflict detection and resolution; a Dolt version where the stored procedure signature changed; corrupted or missing conflict metadata after a crashed merge; calling SettleMerge when the working set is not actually in a conflicted merge state.","solutions":["Re-run the merge from a clean state: ensure the working set is in a conflicted merge (check dolt_status / dolt_conflicts) before calling SettleMerge.","Verify the Dolt server version supports DOLT_CONFLICTS_RESOLVE with '--theirs' and a table argument; upgrade dolt if the procedure signature changed.","Inspect the wrapped inner error (%w) for the underlying SQL error — it names the real cause (unknown procedure, no conflicts, lock timeout).","Ensure no other process concurrently operates on the same database during merge settlement; serialize SettleMerge calls."],"exampleFix":"// before\nif _, err := db.ExecContext(ctx, \"CALL DOLT_CONFLICTS_RESOLVE('--theirs', '\"+table+\"')\"); err != nil {\n\treturn false, fmt.Errorf(\"failed to resolve %s conflicts: %w\", table, err)\n}\n// after\nvar hasConflicts int\nif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dolt_conflicts WHERE `table` = ?\", table).Scan(&hasConflicts); err != nil || hasConflicts == 0 {\n\treturn false, nil // nothing to resolve; skip instead of failing\n}\nif _, err := db.ExecContext(ctx, \"CALL DOLT_CONFLICTS_RESOLVE('--theirs', '\"+table+\"')\"); err != nil {\n\treturn false, fmt.Errorf(\"failed to resolve %s conflicts: %w\", table, err)\n}","handlingStrategy":"try-catch","validationCode":"var n int\nerr := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dolt_conflicts WHERE `table` = ?\", table).Scan(&n)\n// proceed only if err == nil && n > 0 and dolt_status shows an active merge","typeGuard":"func hasActiveMergeConflicts(ctx context.Context, db DBConn, table string) bool {\n\tvar n int\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dolt_conflicts WHERE `table` = ?\", table).Scan(&n); err != nil {\n\t\treturn false\n\t}\n\treturn n > 0\n}","tryCatchPattern":"ok, err := TryAutoResolveMergeConflicts(ctx, db)\nif err != nil {\n\tvar resolveErr *fmt.WrapError // or errors.As on the wrapped driver error\n\tif errors.As(err, &resolveErr) && strings.Contains(err.Error(), \"failed to resolve\") {\n\t\t_, _ = db.ExecContext(ctx, \"CALL DOLT_MERGE('--abort')\") // reset to clean state, then retry SettleMerge\n\t}\n\treturn err\n}","preventionTips":["Always call SettleMerge only right after a merge that reported conflicts; never on a clean working set.","Serialize merge settlement across processes (single writer or lock) to avoid mid-resolve state changes.","Pin and test against the Dolt server version you deploy; stored-procedure behavior changes between versions.","Always unwrap and log the inner %w error — it names the actual SQL failure."],"tags":["dolt","merge-conflicts","sql","storage"],"backgroundTag":"dolt-conflict-resolve-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}