gastownhall/beads · error

publish working set after SQL commit: %w: %w

Error message

publish working set after SQL commit: %w: %w

What it means

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.

Source

Thrown at internal/storage/dolt/store.go:3140

			return nil
		}
		return s.wrapDoltPublicationFailure(ctx, "failed to commit", err)
	}

	return nil
}

// commitWorkingSetAfterSQLCommit preserves the no-replay boundary for a Dolt
// publication that follows an already-visible SQL mutation. commitWorkingSet
// classifies DOLT_COMMIT response loss itself; this wrapper adds the same
// sentinel to earlier publication failures such as a lost DOLT_ADD response.
func (s *DoltStore) commitWorkingSetAfterSQLCommit(ctx context.Context, message string, mode configCommitMode) error {
	err := s.commitWorkingSet(ctx, message, mode)
	if err == nil || errors.Is(err, ErrCommitIndeterminate) || !isIndeterminateCommitResponse(err) {
		return err
	}
	return s.recordDoltPublicationFailure(ctx,
		fmt.Errorf("publish working set after SQL commit: %w: %w", err, ErrCommitIndeterminate))
}

// concludeOpenMerge commits an open merge whose resolution left the working
// set clean, so the merge is actually concluded rather than left open with
// nothing to show for it. It is a no-op when no merge is in progress, and it
// runs on the CALLER'S pinned connection because dolt's merge state is
// session state. isDoltNothingToCommit still absorbs the race where the merge
// closed between the status read and the commit.
func (s *DoltStore) concludeOpenMerge(ctx context.Context, conn *sql.Conn, message string) error {
	var merging bool
	if err := conn.QueryRowContext(ctx, "SELECT is_merging FROM dolt_merge_status").Scan(&merging); err != nil {
		// No merge status to read is no evidence of a merge — keep the old
		// "nothing to commit" behavior rather than failing a resolution.
		return nil //nolint:nilerr // diagnosis only; never a gate
	}
	if !merging {
		return nil
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Do NOT blindly re-commit: first check whether the commit landed (dolt log, dolt_status) to avoid duplicates.
  2. Use bd's recorded publication-failure record (recordDoltPublicationFailure) to inspect what was pending and reconcile.
  3. If the commit landed but the working set is stale, re-run only the publish/sync step.
  4. If it did not land, re-run the commit operation; treat ErrCommitIndeterminate with errors.Is to branch recovery logic.
  5. Harden networking (keepalives, proxy timeouts) between client and Dolt server to reduce indeterminate responses.

Example fix

// before
err := store.Commit(ctx, "msg")
if err != nil { return err } // treats indeterminate like a plain failure
// after
err := store.Commit(ctx, "msg")
if errors.Is(err, doltstore.ErrCommitIndeterminate) {
	// verify with dolt log before retrying
	return reconcilePublication(ctx, err)
}
if err != nil { return err }
Defensive patterns

Strategy: type-guard

Validate before calling

// before interpreting the error
if errors.Is(err, doltstore.ErrCommitIndeterminate) {
	// verify actual state before any retry:
	// bd dolt / dolt log; check whether commit landed
}

Type guard

func isIndeterminateCommit(err error) bool {
	return errors.Is(err, doltstore.ErrCommitIndeterminate)
}

Try / catch

if err := store.Commit(ctx, msg); err != nil {
	if isIndeterminateCommit(err) {
		return verifyAndReconcile(ctx) // check dolt log first, never blind-retry
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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