Skip to content

WriteOperationError

Class: warmhub.WriteOperationError

WriteOperationError(operation_index: int | None, message: str, code: str = 'VALIDATION_ERROR')

A local write refusal, before any request.

Mirrors TypeScript’s WriteOperationError. operation_index is the refused operation’s position in the submission (or the builder); it is None when the refusal is about the whole batch, such as a builder that was already submitted, and the message then carries no Invalid operation at index N: prefix.

code is one of:

  • VALIDATION_ERROR — the default: a malformed or v1 operation, a pinned Shape name, a raw shapeless, and every whole-batch builder refusal;
  • NOT_FOUND — a keep-Shapes revise whose Thing does not exist;
  • RESERVED_NAME — a Thing name under the reserved hub root;
  • ILLEGAL_OP_SEQUENCE — a second add of one name in one submission;
  • a Shape-name preflight code (see preflight_op_diagnostics), such as a built-in or reserved Shape name.

name = 'WarmHubError'

Mirrors TypeScript’s this.name = 'WarmHubError'. to_warmhub_error reads it to recognize an error raised by a different copy of the SDK, where an isinstance check fails.

submission_id = None

The submission this chunk belonged to.

event_request_id = None

The chunk’s deterministic event-request identity.

chunk_ordinal = None

The chunk’s zero-based position in the submission.

code = code

Stable SDK error code or pass-through backend domain code.

message = message

Documentation is not yet available.

status = status

HTTP status from the failing response, when one was available.

hint = hint

Optional human-readable hint surfaced by the backend.

retry_after = None if retry_after is None else min(max(retry_after, 0.0), MAX_RETRY_AFTER_SECONDS)

Seconds to wait before retrying. Present on RATE_LIMITED.

Clamped to MAX_RETRY_AFTER_SECONDS HERE rather than at the one construction site that reads a header. The value reaches this class from four paths — header, REST body, tRPC envelope, and re-normalization — and capping one of them left the stated invariant (“one hostile response must not put the client to sleep for a week”) true only of the path that happened to be written last.

error_code = error_code

Canonical domain code from the response body. Set iff the backend wire carried a structured error.code.

details = decode_error_details(details) if isinstance(details, Mapping) else details

Documentation is not yet available.

kind

Alias for code, matching TypeScript’s get kind().

expected_version

The version the caller asserted, on a lost optimistic-concurrency race. None unless details.reason is "expected_version_mismatch" — pair with current_version.

current_version

The version the server actually holds. Re-read at this version and retry; see expected_version.

lease_expires_at

ISO-8601 instant the blocking read lease expires, or None.

validation_issues

Per-field validation issues. Empty, not None, when the wire carried a different reason — a caller iterating this needs no guard, and an empty loop body is the correct behavior for “no issues reported”.

reset_at

ISO-8601 instant a rate limit lifts, or None.

Distinct from retry_after, which is the transport-level relative delay and is populated from the response envelope rather than from details. When the backend sends structured rate_limit_reset details, both are present and they agree; when it sends only one, the other stays None.

backend_code

Deprecated alias for error_code.

Retained because TypeScript still exposes backendCode during the GH-3533 migration window; dropping it would be a silent surface difference between the clients.

operation_index = operation_index

The refused operation’s position, or None for the whole batch.