Error Reference
Where failures surface depends on the path you are on:
| Path | Failure appears as |
|---|---|
| Onchain | A revert on your transaction, or a PendingTradeRefund / rejection event during settlement |
| Gasless (1CT) | A 400 at submission — or 404 for Position not found — or skipped / success = false in the intent status |
| REST API | An HTTP status code |
Contract errors
Custom errors raised by the protocol. On the onchain path these revert your transaction; on the 1CT path they arrive as encoded revert data in the status reason field.
Market and pair state
| Error | Meaning |
|---|---|
MarketClosed | The market is outside its trading hours |
PairClosed | Trading is disabled for this pair |
UnsupportedChain | Operation not supported on this network |
Collateral and amounts
| Error | Meaning |
|---|---|
UnsupportedToken | Token not accepted by the protocol |
UnsupportedMarginToken | Token cannot be used as margin — usually a tokenIn / lvToken mismatch |
InvalidAmount | Amount is zero, below the minimum, or does not cover the fee |
InsufficientMarginAmount | Position does not hold enough margin for the operation |
InsufficientLiquidityPool | Pool cannot back the requested size |
Leverage and risk
| Error | Meaning |
|---|---|
BelowDegenModeMinLeverage | Resulting leverage below the pair's minimum |
ExceedMaxLeverageAfterMarginRemoval | Removal would push leverage past the maximum |
LiquidatableAfterMarginRemoval | Removal would make the position immediately liquidatable |
ExceedMaxTakeProfitAfterMarginRemoval | Existing take-profit would exceed its bound at the new leverage |
Positions and orders
| Error | Meaning |
|---|---|
NonexistentTrade | Position does not exist — already closed, or the wrong hash |
PositionNotCloseable | Cannot be closed yet — check earliestCloseTime |
InvalidStopLoss | Stop-loss price invalid for this position |
TooManyActiveDecreaseOrders | Per-position TP/SL order cap reached |
CoolingOffPeriod | Temporarily unavailable |
Oracle
| Error | Meaning |
|---|---|
InvalidPrice | Oracle returned an unusable price |
InvalidUpdateFee | msg.value does not cover the oracle update fee |
1CT authorization
| Error | Meaning |
|---|---|
UnauthorizedOperation | The intent targets a position the trader does not own |
Authorization failures are not custom errors
A bad signature, an unauthorized agent, a missing permission bit, and an expired deadline do not revert with a custom error. The intent is skipped with skipReason = INVALID and the transaction succeeds — see Interpreting the result. Do not write a handler that matches on a revert selector for these; match on skipReason.
Some failures surface as Error(string) instead of a custom error, most notably OneClickV2: name taken when authorizing an agent with a name already in use.
Refund reasons
Carried by PendingTradeRefund, ExecuteLimitOrderRejected and LimitOrderRefund as an enum. A refund means the request was rejected at settlement and collateral was returned — nothing reverted.
| # | Reason | Meaning |
|---|---|---|
| 0 | NO | No refund |
| 1 | SWITCH | Feature disabled |
| 2 | PAIR_STATUS | Pair not tradable |
| 3 | AMOUNT_IN | Collateral amount invalid |
| 4 | USER_PRICE | Fill fell outside the acceptable price — the most common one |
| 5 | MIN_NOTIONAL_USD | Position size below the minimum |
| 6 | MAX_NOTIONAL_USD | Position size above the maximum |
| 7 | MAX_LEVERAGE | Leverage above the tier's maximum |
| 8 | TP | Take-profit invalid |
| 9 | SL | Stop-loss invalid |
| 10 | PAIR_OI | Open interest cap for the pair reached |
| 11 | OPEN_LOST | Position would open already in loss beyond the allowed bound |
| 12 | SYSTEM | Internal rejection |
| 13 | FEED_DELAY | Oracle price too stale |
| 14 | PRICE_PROTECTION | Price protection triggered |
| 15 | RESERVE_TOKEN_NOT_ACTIVE | Collateral token disabled |
| 16 | LV_TOKEN_NOT_ACTIVE | Settlement token disabled |
| 17 | MIN_LEVERAGE | Leverage below the minimum |
USER_PRICE usually means the slippage bound was too tight or the price moved between quoting and settlement. Widen the bound, or re-quote closer to submission.
1CT skip reasons
skipReason | Meaning | Fix |
|---|---|---|
INVALID | Signature invalid, agent unauthorized, permission bit missing, or deadline passed | Check authorization, deadline, EIP-712 structure and primaryType |
NONCE | Nonce not strictly increasing, or outside the time window | Re-sign with a larger nonce |
FEE | Execution fee could not be collected | Check fee-token balance and Diamond allowance |
UNKNOWN | Unclassified | Report it |
See Submit & Track.
1CT submission errors
All return 400 except Position not found, which returns 404. If you branch on the status code to decide whether to retry, note that the one retryable failure is the 404.
| Message contains | Cause |
|---|---|
deadline already passed | deadline is in the past |
nonce too old | Nonce more than 2 days old |
nonce too far in future | Nonce more than 5 minutes ahead |
invalid action | Action outside [0, 13] |
invalid … address | Malformed trader or feeToken |
must not be empty | Empty actionData or signature |
antiDdosFee mismatch | Fee config cache older than ~120 seconds |
feeToken not supported | Token not configured for this action |
anti-ddos not enabled | Free action signed with a non-zero fee, or with a feeToken other than 0x0000…0000 — a disabled action needs both to be zero |
Position not found (404) | Position not yet indexed — see the caveat |
Solidity panics
Occasionally surfaced through the 1CT reason field.
| Code | Meaning |
|---|---|
0x01 | Assertion failed |
0x11 | Arithmetic overflow or underflow |
0x12 | Division by zero |
0x21 | Invalid enum value |
0x22 | Invalid storage encoding |
0x31 | Pop from an empty array |
0x32 | Array index out of bounds |
0x41 | Out of memory |
0x51 | Call to an uninitialized function |
Decoding revert data
import { decodeErrorResult, type Abi } from 'viem'
const STANDARD_ERRORS = [
{ type: 'error', name: 'Error', inputs: [{ name: 'message', type: 'string' }] },
{ type: 'error', name: 'Panic', inputs: [{ name: 'code', type: 'uint256' }] },
] as const satisfies Abi
const PROTOCOL_ERRORS = [
{ type: 'error', name: 'MarketClosed', inputs: [] },
{ type: 'error', name: 'NonexistentTrade', inputs: [] },
{ type: 'error', name: 'InsufficientLiquidityPool', inputs: [] },
// …add the errors your integration surfaces
] as const satisfies Abi
export function decodeRevert(data: `0x${string}`): string {
for (const abi of [STANDARD_ERRORS, PROTOCOL_ERRORS]) {
try {
const decoded = decodeErrorResult({ abi, data })
if (decoded.errorName === 'Error') return String(decoded.args?.[0])
if (decoded.errorName === 'Panic') return `Panic 0x${(decoded.args?.[0] as bigint).toString(16)}`
return decoded.errorName
} catch {
// try the next ABI
}
}
return 'Unknown error'
}HTTP status codes
| Code | Meaning |
|---|---|
200 | Success |
400 | Invalid parameters |
404 | Resource not found |
500 | Server error — retry with backoff |