Errors and failure handling

Decode program errors from the IDL and handle the failures integrators meet most often.

Updated Nov 9, 2026

A failed simulation returns something like {"InstructionError":[0,{"Custom":6034}]}. Both programs ship their error table in the IDL, so the mapping from a code to a name and message should be derived, never transcribed. The complete tables are in the errors reference.

Decoding

program-errors.ts
import { IDL, leverageDelegateIdl } from "@omnipair/dusk-sdk"
 
type IdlError = { code: number; name: string; msg?: string }
 
function table(idl: unknown) {
  const errors = (idl as { errors?: IdlError[] }).errors ?? []
  return new Map(errors.map((entry) => [entry.code, entry]))
}
 
const DUSK = table(IDL)
const DELEGATE = table(leverageDelegateIdl())
 
export function describe(code: number) {
  const entry = DUSK.get(code) ?? DELEGATE.get(code)
  return entry ? `${entry.msg ?? entry.name} (${entry.name})` : null
}

Dusk codes start at 6000 and the delegate's at 6000 too, so decide which program failed from the instruction index before looking the code up; the app checks the Dusk table first only because most transactions target it.

Failures you will meet

ErrorWhyWhat to do
SlippageExceededThe market moved past the minimum output you sentRe-quote and retry; do not loosen tolerance blindly
InsufficientCashReserve0 / …1, InsufficientLiquidityOnly cash can leave; that side is lent outSmaller size, or wait for repayments
BorrowingPowerExceededThe borrow exceeds the buffered borrow limitRe-run the capacity preview and borrow within maxBorrowAmount
DailyLimitExceededThe asset's 24-hour public borrow bucket is spentBorrow less or wait for the bucket to refill
InsufficientMarketHealth, InsufficientBorrowHeadroomThe action would breach the market's health floor or an hLP vault's funding headroomReduce size; check previewHlpDepositCapacity
ReduceOnlyMode, MarketReduceOnly, ReduceOnlyHasDebtThe protocol or market is in reduce-only, or a reduce-only withdrawal would leave debtOnly repayments and exits are allowed
MarketNotStarted, InstructionNotLiveThe market's trading start is in the future, or the instruction is gated during launchWait for the start time
LaunchRateLimitSplitTransactionTwo swap-like actions on one market in one transaction while the launch limiter is onSend them separately
Undercollateralized, NotUndercollateralized, PositionNotLiquidatableThe position is not in the state the instruction requiresRe-read the position and refresh the liquidation preview
LiquidationRepayTooLargeA fill exceeds the program's permitted partial or full amountUse the program-previewed repayment
LeverageMultiplierTooHigh, LeverageInitialMarginTooLowThe position breaks the absolute multiplier or its stored/admission margin termsLower the multiplier or size, or add margin
LeveragePositionNotLiquidatableHealth has not failedNothing to do
HlpSettlementUnavailable, HlpNotLiquidatableThe vault's settlement reference diverged, or it is not exhaustedWait for a settlement, or nothing to do
UtilizationGuardExceeded, ProposalTimelockNotReady, ProposalExecutionWindowExpired, ProposalStaleOperator-bundle timing, current-state commitments or utilization guardsWait, or re-propose if stale
InvalidSignerA harvest by someone who is neither owner, recipient nor harvest authoritySign with an allowed key
UnsupportedAssetDecimalsA mint with more than nine decimalsUnsupported
InvalidTokenProgram, InvalidTokenAccountWrong token program for the mint, or an account that is not the canonical ATADerive with the mint's own program
Delegate TriggerNotMet, InvalidOrderThe order's condition is not met, or it no longer matches the positionTyped skip; re-read and re-evaluate

Failures that are not program errors

  • Blockhash expired. Rebuild after re-reading state; never re-sign a transaction whose result is unknown.
  • Account not found or wrong discriminator. Your client and the deployment disagree; check the pin on Addresses.
  • Preview or capacity returned, transaction failed. Previews skip permission, reduce-only, token-account, referral, slippage and freshness checks. Simulate the real transaction.
  • Indexer 409 or 503. Identity mismatch or freshness not met; see read API and streams. Never fall back to a different deployment.

Expected races

Anything that depends on someone else's state can lose a race: an order already executed, a liquidation already filled, a position already repaid, an operator bundle already executed or replaced. Treat these as typed skips rather than failures, re-read the accounts, and re-evaluate. The keeper operations page has the full list.