KitError carrying structured fields. Read
those fields to decide how to handle each error, instead of parsing error
strings. Errors surface from every Earn operation, including
deposit,
withdraw, and
preview quotes.
KitError fields
Check
code or name for specific handling, type for handling a whole
category, and recoverability to decide whether to retry.
Error types
Common Earn error codes
Check these codes for specific handling. Reference the JavaScript constant asEarnError.<NAME>.code. The underlying error.name includes the EARN_
prefix.
Helper functions
Import error utilities from@circle-fin/app-kit (or @circle-fin/earn-kit if
you’re using only the standalone Earn Kit):
TypeScript
Handling errors
This example shows a complete error handling pattern for a deposit, including a check for a specific error code:TypeScript
Resume a failed operation with kit.earn.retry
Deposits and withdrawals run through multiple phases (fetchParams, approve,
execute). When a failure has recoverability === 'RESUMABLE', the operation
stopped mid-flow with some phases already complete. Call kit.earn.retry(error)
to resume from the failed step instead of restarting from scratch. Reuse the
caught KitError. It carries the original inputs and step progress.
TypeScript
isRetryableError for errors where the full operation can be retried from
the beginning. Use isResumableError when the operation should continue from
the failed step.
Retry re-fetches execution parameters and might re-submit the execute
transaction. Treat it as best-effort recovery. If a prior attempt broadcast the
execute transaction but failed before observing the receipt, that transaction
might still be in flight.
Observe step events
App Kit forwards Earn step events to handlers registered on the kit. Use them to render progress or log which phase a failure occurred in. Register a handler withkit.on(); detach it with kit.off().
TypeScript
earn.approve, earn.deposit, earn.withdraw,
earn.crossChainDeposit, earn.crossChainDepositStatus. Each payload carries
the operation, method (phase), and values for that step.
Partial success in getVaults
getVaults uses partial success semantics: a network, auth, or service failure
throws a KitError, but a single vault that can’t be resolved is returned in
the errors array instead of throwing. One bad vault doesn’t fail the whole
batch.
TypeScript
Errors from your wallet adapter
deposit and withdraw submit transactions through the wallet adapter you
supply (for example, @circle-fin/adapter-viem-v2). Wallet and RPC failures
during execution surface as KitErrors with these type categories:
BALANCE(codes in the 9000s): insufficient token balance, gas, or allowance.FATAL.ONCHAIN(codes in the 5000s): simulation or execution failures.FATAL.RPC(codes in the 4000s): RPC endpoint or nonce issues.RETRYABLE.INPUT_USER_CANCELLED(1099): user rejected the wallet prompt.FATAL.
type and recoverability rather than enumerating every code.
Common error scenarios
Rate limiting
Rate limit responses areRATE_LIMIT errors with RETRYABLE recoverability.
Apply the backoff-and-retry pattern from the deposit example.
Earn rate limits are enforced at multiple layers; all relevant layers must be
satisfied for a request to succeed.
In permissionless mode (no API key), only the per-IP and global limits apply.
Using an API key adds the per-entity limit, which gives more headroom for
server-side integrations sending traffic from multiple IPs.
To avoid hitting rate limits in production:
- Obtain a Circle API key
from the Circle Console and pass it on
each operation as
config.apiKey. For a restricted key, select the “App Kits” product permission when creating the key. - Cache
getVaultsresults. Vault metadata changes infrequently. Refreshing every 30 to 60 seconds is sufficient. - Batch vault address lookups. Pass up to 20 addresses in a single
getVaultscall instead of calling it once per address.