PerpsError with a numeric code, the originating tool (provider), and a human-readable message.
PerpsError class, which carries the numeric error code:
Discriminating errors
The error model is flat: there is one class —PerpsError — and you branch on its numeric .code (a PerpsErrorCode). There are no error subclasses to instanceof. A non-2xx API response is re-hydrated into a PerpsError carrying the backend’s code and message; error.tool names the originating provider when the error came from one.
SDK-originated errors (for example a missing agent key) carry canonical messages from the
PerpsErrorMessage enum.
Error Code Ranges
Error codes use the 2000+ range to avoid collision with the main LI.FI API (which uses 1000+):Error Code Reference
Base Errors (2000-2009)
Authentication Errors (2010-2019)
Trading Errors (2020-2039)
Nonce Errors (2040-2049)
Payload Errors (2050-2059)
Routing Errors (2060-2069)
SDK Error Code Constants
The SDK exportsPerpsErrorCode for type-safe error handling:
Troubleshooting
ExchangeRejected (2020)
The provider backend rejected the request. Check:- Order parameters are valid (size within limits, price within bounds)
- The market is active and not in maintenance
- Request body matches the expected schema
InsufficientMargin (2021)
Not enough margin for the requested order. Check:- Account has sufficient USDC balance
- Existing positions don’t consume too much margin
- Reduce leverage or order size
InsufficientBalance (2022)
Account lacks funds for the operation. Check:- Deposit sufficient funds to your account
- Check balances with
getAccount()
SignatureInvalid (2010)
The signature could not be verified. Check:- The correct wallet/agent signed the
typedData - The
typedDatawas not modified after creation - The nonce has not expired (re-call
createActionto get fresh data)
AgentUnauthorized (2011)
The agent wallet is not approved on the provider. Check:- The setup flow completed successfully (via
checkSetupandexecuteProviderSetupAction) - The agent address matches what was authorized
- The authorization has not been revoked
TermsNotAccepted (2012)
The address has not accepted the current terms of service. Check:- Fetch the current terms and acceptance status with
GET /v1/perps/meta/terms?address= - Have the address accept the current
termsVersionbefore performing an action
MarketNotFound (2023)
The symbol doesn’t exist on the specified provider. Check:- Use
getAssets()to list valid asset IDs - Asset IDs are case-sensitive (use
BTC, notbtc) - The asset hasn’t been delisted
OrderNotFound (2024)
The order ID doesn’t exist. Check:- Use the correct
orderId(from the submit response) - The order may have already been fully filled or cancelled
- Verify the
providerparameter matches where the order was placed
PositionNotFound (2025)
No position exists for the specified symbol. Check:- Verify you have an open position for this symbol
- Use
getPositions()to list current positions
AccountNotFound (2026)
The address has not been onboarded on the specified provider. Check:- The user has completed the setup flow for the provider (see Hyperliquid / Setup)
- For Lighter, an account is created on first deposit
- The
providerparameter matches a provider where the user actually holds an account
InvalidNonce (2040)
The nonce in the request failed validation. Check:- The
typedDatawas not modified after creation - Re-call the create endpoint to get fresh payloads
NonceAlreadyUsed (2041)
The nonce has already been consumed by a previous request. This typically happens when:- Submitting the same signed payload twice
- Re-submitting after a successful operation
NonceExpired (2042)
The nonce has exceeded its time-to-live. Payloads expire after a short period for security. Check:- Sign and submit payloads promptly after creation
- Re-call the create endpoint to get fresh payloads
PayloadMismatch (2050)
The signed payload doesn’t match what was stored server-side. This can happen if:- The
typedDatawas modified before signing - A different payload was substituted
typedData returned from the create endpoint without modification.
ThirdPartyError (2004)
An external service (typically the provider) returned an error. Check:- Provider may be experiencing issues
- Retry after a short delay
- Check provider status pages for outages
TimeoutError (2003)
The request exceeded the timeout limit. Check:- Network connectivity
- Provider may be experiencing high latency
- Retry the operation