Errors & Recovery
Handle SDK errors and check whether the original operation reached the chain.
Read the error code#
The CommonJS SDK throws an Error with code and message fields. Branch on code and show the user an action they can take. Keep request envelopes and private account data out of diagnostic output.
These errors catch changed contracts, budgets and request content, as well as unresolved broadcasts. Resolve the reason before attempting to accept the original request again.
Common error codes#
| Code | Reason | Next step |
|---|---|---|
| PIN_MISMATCH | The deployment or authority changed | Check configuration against the intended chain and contracts |
| STORE_MISMATCH | Saved policy or observed state no longer matches | Reconcile the original ledger; keep its records |
| CAPACITY_EXCEEDED | Funding or its configured limit is too small | Fund within the agreed terms before retrying |
| BUDGET_EXCEEDED | Prepared purchases exceed the manager budget | Approve a new policy or session separately |
| REQUEST_CONFLICT | A prepared ID has different content or price | Use its original request or assign a new job ID |
| REQUEST_MISMATCH | Content or price differs from the server calculation | Correct the request or server billing context |
| REQUEST_EXPIRED | The signed deadline passed | Renew the same request's signature if permitted |
| LIFECYCLE_UNCERTAIN | A broadcast outcome is unresolved | Recover and check chain state |
| MANAGER_EXPIRED | The application policy expired | Stop new requests and settle before claim rights end |
| SESSION_NOT_OPEN | The session is unfunded or closing | Check its funding and close state |
Recover after a timeout#
A validation failure and a broadcast timeout need different handling. After submission, the transaction may succeed even if its response is lost. Save the intent and hash, then recover chain state before another mutation.
try {
await merchant.settle();
} catch (error) {
if (error.code === "LIFECYCLE_UNCERTAIN") {
await merchant.recover();
// Review the recovered intent and state before an explicit retry.
} else {
throw error;
}
}Check state before retrying#
Use session, hold and transaction state to choose the retry, rather than matching an error message. Repeating a settled target can be idempotent. Changing content under the same request ID is a conflict.
Stop authorization when RPC reads fail the freshness check, and wait for the RPC and clock to recover. Investigate reorganized or backward state instead of removing the stored observation floor.