{"record":{"id":"1655cbec2fdc4214","repo":"gastownhall/beads","slug":"publish-working-set-after-sql-commit-w-w","errorCode":null,"errorMessage":"publish working set after SQL commit: %w: %w","messagePattern":"publish working set after SQL commit: %w: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":3140,"sourceCode":"\t\t\treturn nil\n\t\t}\n\t\treturn s.wrapDoltPublicationFailure(ctx, \"failed to commit\", err)\n\t}\n\n\treturn nil\n}\n\n// commitWorkingSetAfterSQLCommit preserves the no-replay boundary for a Dolt\n// publication that follows an already-visible SQL mutation. commitWorkingSet\n// classifies DOLT_COMMIT response loss itself; this wrapper adds the same\n// sentinel to earlier publication failures such as a lost DOLT_ADD response.\nfunc (s *DoltStore) commitWorkingSetAfterSQLCommit(ctx context.Context, message string, mode configCommitMode) error {\n\terr := s.commitWorkingSet(ctx, message, mode)\n\tif err == nil || errors.Is(err, ErrCommitIndeterminate) || !isIndeterminateCommitResponse(err) {\n\t\treturn err\n\t}\n\treturn s.recordDoltPublicationFailure(ctx,\n\t\tfmt.Errorf(\"publish working set after SQL commit: %w: %w\", err, ErrCommitIndeterminate))\n}\n\n// concludeOpenMerge commits an open merge whose resolution left the working\n// set clean, so the merge is actually concluded rather than left open with\n// nothing to show for it. It is a no-op when no merge is in progress, and it\n// runs on the CALLER'S pinned connection because dolt's merge state is\n// session state. isDoltNothingToCommit still absorbs the race where the merge\n// closed between the status read and the commit.\nfunc (s *DoltStore) concludeOpenMerge(ctx context.Context, conn *sql.Conn, message string) error {\n\tvar merging bool\n\tif err := conn.QueryRowContext(ctx, \"SELECT is_merging FROM dolt_merge_status\").Scan(&merging); err != nil {\n\t\t// No merge status to read is no evidence of a merge — keep the old\n\t\t// \"nothing to commit\" behavior rather than failing a resolution.\n\t\treturn nil //nolint:nilerr // diagnosis only; never a gate\n\t}\n\tif !merging {\n\t\treturn nil\n\t}","sourceCodeStart":3122,"sourceCodeEnd":3158,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L3122-L3158","documentation":"After the SQL-level DOLT_COMMIT succeeds, the working set must still be published (working-set ref updated). If commitWorkingSet returns an error that looks like an indeterminate commit response — the outcome is unknown (e.g. connection dropped after the server accepted the write) — this error records the failure via recordDoltPublicationFailure and wraps both the original error and ErrCommitIndeterminate. It signals that the commit MAY have landed but its publication state is uncertain, requiring manual verification.","triggerScenarios":"The publish step after a SQL commit fails with an ambiguous response: connection lost after DOLT_COMMIT was sent, timeout with unknown server-side outcome, or isIndeterminateCommitResponse matching an ambiguous driver error.","commonSituations":"Remote Dolt server network partition mid-commit; idle connection reaped by a proxy/firewall exactly during publish; embedded Dolt process crash between commit and publication.","solutions":["Do NOT blindly re-commit: first check whether the commit landed (dolt log, dolt_status) to avoid duplicates.","Use bd's recorded publication-failure record (recordDoltPublicationFailure) to inspect what was pending and reconcile.","If the commit landed but the working set is stale, re-run only the publish/sync step.","If it did not land, re-run the commit operation; treat ErrCommitIndeterminate with errors.Is to branch recovery logic.","Harden networking (keepalives, proxy timeouts) between client and Dolt server to reduce indeterminate responses."],"exampleFix":"// before\nerr := store.Commit(ctx, \"msg\")\nif err != nil { return err } // treats indeterminate like a plain failure\n// after\nerr := store.Commit(ctx, \"msg\")\nif errors.Is(err, doltstore.ErrCommitIndeterminate) {\n\t// verify with dolt log before retrying\n\treturn reconcilePublication(ctx, err)\n}\nif err != nil { return err }","handlingStrategy":"type-guard","validationCode":"// before interpreting the error\nif errors.Is(err, doltstore.ErrCommitIndeterminate) {\n\t// verify actual state before any retry:\n\t// bd dolt / dolt log; check whether commit landed\n}","typeGuard":"func isIndeterminateCommit(err error) bool {\n\treturn errors.Is(err, doltstore.ErrCommitIndeterminate)\n}","tryCatchPattern":"if err := store.Commit(ctx, msg); err != nil {\n\tif isIndeterminateCommit(err) {\n\t\treturn verifyAndReconcile(ctx) // check dolt log first, never blind-retry\n\t}\n\treturn err\n}","preventionTips":["Never blind-retry commits when ErrCommitIndeterminate is present — verify with dolt log first.","Use stable connections (keepalives) between client and Dolt server to cut ambiguous failures.","Reconcile via bd's recorded publication-failure record before re-committing.","Keep client and engine versions current to reduce ambiguous response paths."],"tags":["go","dolt","commit","indeterminate","publication"],"backgroundTag":"commit-outcome-indeterminate","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}