Transient Retry
client.commit.apply(...) and OperationBuilder.commit(...) automatically retry some ambiguous first-chunk failures: timeouts, dropped connections, and server 5xx responses on the very first stream append, where no operation has been acknowledged yet.
In plain terms: simple single-op writes retry automatically; multi-op writes and writes using advanced stream options surface ambiguous failures as PartialStreamSubmissionError. If the backend deterministically rejects every submitted operation, the SDK throws AllStreamOperationsFailedError with the per-op failure ledger on error.result and error.operations.
Auto-retry is conservative — it only fires when every condition holds:
- The first chunk contains exactly one operation (multi-op chunks are rejected because the backend applies each op in its own transaction; a mid-chunk failure may have committed an arbitrary prefix).
- No
streamIdwas supplied (manual-resume mode bypasses retry; internal resume bookkeeping does not affect this condition).
When auto-retry fires, the SDK mints a fresh streamId and re-issues the operation. The retry does not prove the original attempt did not land — definite rejections on the retry are wrapped as PartialStreamSubmissionError so the “inspect repo state before continuing” guarantee survives. Callers needing safe retry should make add operations idempotent with skipExisting: true — pass it via client.commit.apply’s options or set it on each OperationBuilder.add(...) op directly.
For callers, a successful retry behaves like a single successful submission: the method resolves with the server’s operation results.
Advanced Stream Continuation
Section titled “Advanced Stream Continuation”streamId is an advanced continuation option for caller-managed streams — situations where your code chose and retained a stream ID before submission began and is coordinating the stream externally. Supplying streamId signals that you are managing the stream lifecycle yourself; the SDK disables automatic retry for that submission because it cannot safely mint a fresh stream ID on your behalf.
Because PartialStreamSubmissionError does not expose a generated stream ID, callers who did not already hold their own stream ID before a high-level submission failure cannot use streamId to resume after the fact. In that situation, inspect repository state and submit only the operations known not to have landed.
streamId is the only advanced continuation field accepted by client.commit.apply(...) and OperationBuilder.commit(...).
Tuning Retry
Section titled “Tuning Retry”Pass retry: false to disable automatic retry:
await client.commit.apply(org, repo, message, operations, { retry: false })Pass a RetryPolicyOptions value to override defaults:
await client.commit.apply(org, repo, message, operations, { retry: { maxAttempts: 4, baseDelayMs: 100, maxDelayMs: 1000, },})OperationBuilder.commit(...) accepts the same retry option.
Partial Submissions
Section titled “Partial Submissions”The SDK throws PartialStreamSubmissionError whenever an ambiguous or partial append outcome cannot be reduced to a clean success or definite failure. This covers both:
- Mid-stream failures. A multi-chunk submission whose first chunks acknowledged but a later chunk failed ambiguously.
acknowledgedOperationCountcounts every operation covered by append responses, even when those responses contain sparse or empty result rows.completedOperationscontains the returned success and noop rows, so its length may be smaller. - First-chunk ineligible-for-retry failures. The first append fails ambiguously, but auto-retry is disabled (
retry: false) or ineligible (a multi-op first chunk or manual-resume mode). Both progress fields are empty, but the failed append may still have landed server-side.
In every case, the failed append may have landed server-side, so inspect repository state before submitting additional operations.
After OperationBuilder.commit(...) throws PartialStreamSubmissionError, that builder is sealed: later mutation or commit calls fail before transport. Reconcile repository state, then create a new builder containing only operations known not to have landed.
Definite request-level rejections propagate as WarmHubError with the original kind and code. Examples include UNAUTHENTICATED, FORBIDDEN, VALIDATION_ERROR, and RATE_LIMITED. Definite operation-level rejections can also resolve as mixed partial results; when every operation is rejected, they throw AllStreamOperationsFailedError so callers can still inspect each failed op.
Practical Rule
Section titled “Practical Rule”Retry automatically when the SDK returns success or when a normal retryable WarmHubError is safe for your workload. When you catch PartialStreamSubmissionError, use acknowledgedOperationCount and completedOperations as recovery evidence, then treat repository state as the source of truth before deciding what to submit next. When you catch AllStreamOperationsFailedError, use error.operations to fix the rejected inputs before retrying.