Skip to main content
Every error the SDK throws extends KashProtocolError and carries a stable string code (see the exported ErrorCode), structured context, and isRetryable / isOperational flags. The Python SDK uses the same class names and codes.

Error classes

Refusals checked before signing include InvalidState (market not active) and a frozen market.

Sending: which failures are safe to retry

Every error raised after signing carries the transaction signature (context.signature, and .signature on the two transaction error classes), computed before the send.
WAIT_RECEIPT_FAILED is deliberately not retryable. Rebuilding takes a fresh blockhash, which makes a new transaction; if the first one landed, sending both doubles the trade. Check the signature’s status first.

Canonical handling

Use the static is() guards rather than instanceof; they work across module copies and bundles.

Reads

A position or token account that does not exist reads as a balance of zero, because the program creates neither until there is something to hold. A market, config or template that does not exist is an error (ACCOUNT_NOT_FOUND), and an account owned by a different program (wrong cluster or program id) is ACCOUNT_OWNER_MISMATCH. An RPC failure is a retryable KashChainError, never a zero.

isOperational and isRetryable

isOperational: true means a known failure mode: the input or the chain state is the cause. isRetryable: true means a fresh attempt may succeed without changing the input. The flags are independent: a simulation refusal is operational but not retryable.