Skip to content

Error Reference

Where failures surface depends on the path you are on:

PathFailure appears as
OnchainA 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 APIAn 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

ErrorMeaning
MarketClosedThe market is outside its trading hours
PairClosedTrading is disabled for this pair
UnsupportedChainOperation not supported on this network

Collateral and amounts

ErrorMeaning
UnsupportedTokenToken not accepted by the protocol
UnsupportedMarginTokenToken cannot be used as margin — usually a tokenIn / lvToken mismatch
InvalidAmountAmount is zero, below the minimum, or does not cover the fee
InsufficientMarginAmountPosition does not hold enough margin for the operation
InsufficientLiquidityPoolPool cannot back the requested size

Leverage and risk

ErrorMeaning
BelowDegenModeMinLeverageResulting leverage below the pair's minimum
ExceedMaxLeverageAfterMarginRemovalRemoval would push leverage past the maximum
LiquidatableAfterMarginRemovalRemoval would make the position immediately liquidatable
ExceedMaxTakeProfitAfterMarginRemovalExisting take-profit would exceed its bound at the new leverage

Positions and orders

ErrorMeaning
NonexistentTradePosition does not exist — already closed, or the wrong hash
PositionNotCloseableCannot be closed yet — check earliestCloseTime
InvalidStopLossStop-loss price invalid for this position
TooManyActiveDecreaseOrdersPer-position TP/SL order cap reached
CoolingOffPeriodTemporarily unavailable

Oracle

ErrorMeaning
InvalidPriceOracle returned an unusable price
InvalidUpdateFeemsg.value does not cover the oracle update fee

1CT authorization

ErrorMeaning
UnauthorizedOperationThe 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.

#ReasonMeaning
0NONo refund
1SWITCHFeature disabled
2PAIR_STATUSPair not tradable
3AMOUNT_INCollateral amount invalid
4USER_PRICEFill fell outside the acceptable price — the most common one
5MIN_NOTIONAL_USDPosition size below the minimum
6MAX_NOTIONAL_USDPosition size above the maximum
7MAX_LEVERAGELeverage above the tier's maximum
8TPTake-profit invalid
9SLStop-loss invalid
10PAIR_OIOpen interest cap for the pair reached
11OPEN_LOSTPosition would open already in loss beyond the allowed bound
12SYSTEMInternal rejection
13FEED_DELAYOracle price too stale
14PRICE_PROTECTIONPrice protection triggered
15RESERVE_TOKEN_NOT_ACTIVECollateral token disabled
16LV_TOKEN_NOT_ACTIVESettlement token disabled
17MIN_LEVERAGELeverage 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

skipReasonMeaningFix
INVALIDSignature invalid, agent unauthorized, permission bit missing, or deadline passedCheck authorization, deadline, EIP-712 structure and primaryType
NONCENonce not strictly increasing, or outside the time windowRe-sign with a larger nonce
FEEExecution fee could not be collectedCheck fee-token balance and Diamond allowance
UNKNOWNUnclassifiedReport 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 containsCause
deadline already passeddeadline is in the past
nonce too oldNonce more than 2 days old
nonce too far in futureNonce more than 5 minutes ahead
invalid actionAction outside [0, 13]
invalid … addressMalformed trader or feeToken
must not be emptyEmpty actionData or signature
antiDdosFee mismatchFee config cache older than ~120 seconds
feeToken not supportedToken not configured for this action
anti-ddos not enabledFree 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.

CodeMeaning
0x01Assertion failed
0x11Arithmetic overflow or underflow
0x12Division by zero
0x21Invalid enum value
0x22Invalid storage encoding
0x31Pop from an empty array
0x32Array index out of bounds
0x41Out of memory
0x51Call to an uninitialized function

Decoding revert data

ts
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

CodeMeaning
200Success
400Invalid parameters
404Resource not found
500Server error — retry with backoff

Trading perpetuals involves risk. Nothing here is financial advice.