Skip to main content

Error Codes

Complete reference of Seesaw protocol error codes.

Overview

Error codes are organized by category for easy identification:

Market Errors (0x1001 - 0x100F)

CodeNameDescriptionResolution
0x1001MarketNotFoundMarket account does not existVerify market ID and wait for creation
0x1002MarketExistsMarket account already existsUse existing market
0x1003InvalidStateOperation not valid in current market stateCheck market state before operation
0x1004TradingNotStartedTrading has not begun (start price not snapshotted)Wait for start price snapshot
0x1005TradingEndedTrading period has endedCannot place new orders
0x1006AlreadySnapshottedPrice snapshot already recordedNo-op, snapshot exists
0x1007AlreadyResolvedMarket outcome already determinedNo-op, proceed to settlement
0x1008MarketNotResolvedMarket not yet resolvedWait for resolution
0x1009MarketClosedMarket has been closedMarket lifecycle complete
0x100AMarketExpiredMarket has expired (past expiration window)Use force close if available
0x100BTooEarlyOperation attempted too earlyWait for appropriate time
0x100CEpochNotStartedEpoch has not started yetWait for t_start
0x100DEpochNotEndedEpoch has not ended yetWait for t_end
0x100ENotOwnerCaller is not the owner of the resourceUse correct wallet
0x100FPositionsRemainingUnsettled positions exist; cannot close marketSettle all positions first

Market Error Examples

// Check if market exists before interacting
try {
  const market = await program.account.market.fetch(marketPda);
} catch (e) {
  if (e.code === 0x1001) {
    console.log('Market not yet created, waiting...');
  }
}

// Handle trading state
if (error.code === 0x1005) {
  console.log('Trading has ended for this market');
  // Redirect to settlement or next market
}

Oracle Errors (0x2001 - 0x2008)

CodeNameDescriptionResolution
0x2001InvalidOracleOwnerOracle account has invalid ownerVerify Pyth program ID
0x2002InvalidOracleFeedOracle feed is invalid or malformedCheck feed account data
0x2003OracleMismatchPyth feed does not match market configurationUse correct feed for market
0x2004StaleOracleOracle price data is staleWait for fresh price update
0x2005InvalidPriceOracle reported an invalid price (zero or negative)Check feed status
0x2006ConfidenceTooWideOracle confidence interval exceeds maximum allowed ratioWait for more certain price
0x2007OracleNotTradingOracle status is not TradingWait for feed to resume
0x2008FeedIdMismatchPyth feed ID does not match expected feed ID stored in marketVerify feed ID

Oracle Error Examples

// Handle stale oracle
if (error.code === 0x2004) {
  console.log('Oracle price is stale, retrying in 1 second...');
  await sleep(1000);
  // Retry operation
}

// Handle confidence issues
if (error.code === 0x2006) {
  console.log('Price confidence too wide, market may be volatile');
  // Consider waiting for better conditions
}

Order Errors (0x3001 - 0x300B)

CodeNameDescriptionResolution
0x3001InvalidQuantityOrder quantity is invalid (zero or exceeds maximum)Use valid quantity (> 0)
0x3002InsufficientCollateralInsufficient collateral for buy orderDeposit more USDC
0x3003InsufficientSharesInsufficient shares for sell orderBuy shares first or reduce quantity
0x3004OrderbookFullOrder book has reached maximum capacity (64 per side)Wait for orders to clear
0x3005OrderNotFoundOrder not found in the order bookOrder may have been filled or cancelled
0x3006WouldCrossPostOnly order would immediately match (cross the spread)Adjust price or use Limit order
0x3007AlreadySettledPosition has already been settledNo-op, already processed
0x3008NoPositionUser has no position in this marketTrade first to create position
0x3009PriceTooLowPrice is too low (must be at least 1 basis point)Use price >= 1 bps
0x300APriceTooHighPrice is too high (must be less than 10000 basis points)Use price < 10000 bps
0x300BCollateralTooLowCollateral calculation resulted in zero (minimum 1 required)Increase quantity or price

Order Error Examples

// Handle insufficient collateral
if (error.code === 0x3002) {
  const required = calculateCollateral(price, quantity);
  console.log(`Need ${required} USDC to place this order`);
  // Prompt user to deposit
}

// Handle PostOnly rejection
if (error.code === 0x3006) {
  console.log('Your PostOnly order would match immediately');
  // Either adjust price or switch to Limit
}

// Handle order not found
if (error.code === 0x3005) {
  console.log('Order not found - may have been filled');
  // Refresh order book state
}

Math Errors (0x4001)

CodeNameDescriptionResolution
0x4001MathOverflowArithmetic overflow or underflowUse smaller values or check inputs

Math Error Example

// This typically indicates a bug or extreme values
if (error.code === 0x4001) {
  console.error('Math overflow detected - this should not happen');
  console.error('Check your input values:', { price, quantity });
  // Report as bug if values are reasonable
}

Account Errors (0x5001 - 0x5007)

CodeNameDescriptionResolution
0x5001InvalidAccountTypeAccount discriminator does not match expected typeUse correct account
0x5002InvalidAccountOwnerAccount owner is not the expected programVerify account ownership
0x5003InvalidPDAPDA derivation does not match expected seedsCheck PDA derivation
0x5004AlreadyInitializedAccount has already been initializedUse existing account
0x5005InsufficientRentExemptionAccount does not have enough lamports for rent exemptionAdd more SOL
0x5006InsolvencyDetectedVault solvency invariant violatedCritical error - contact support
0x5007OrderIdOverflowOrder ID counter overflowExtremely rare - contact support

Account Error Examples

// Handle PDA derivation errors
if (error.code === 0x5003) {
  // Verify PDA derivation
  const [expectedPda] = PublicKey.findProgramAddressSync(
    [Buffer.from('seesaw'), Buffer.from('market'), marketIdBuffer],
    programId
  );
  console.log('Expected PDA:', expectedPda.toString());
}

// Handle insolvency (critical)
if (error.code === 0x5006) {
  console.error('CRITICAL: Insolvency detected - contact support immediately');
  // This indicates a protocol-level issue
}

Position Errors (0x6001 - 0x6002)

CodeNameDescriptionResolution
0x6001PositionLimitExceededPosition size exceeds maximum allowedReduce position size
0x6002ProtocolPausedProtocol is pausedWait for protocol to resume

Position Error Examples

// Handle protocol pause
if (error.code === 0x6002) {
  console.log('Protocol is currently paused');
  // Check announcements for more info
}

Token Architecture Errors (0x7001 - 0x7006)

CodeNameDescriptionResolution
0x7001NotImplementedInstruction not implemented yetFeature coming soon
0x7002ActiveMarketExistsActive market already exists for this assetUse existing market
0x7003CannotExpireCannot expire market (not past expiration window or already resolved)Wait for expiration window
0x7004InvalidTokenTypeInvalid token type for redemptionUse correct token (YES/NO)
0x7005InvalidRedemptionCannot redeem tokens that are not winningOnly winning shares pay out
0x7006VaultBalanceMismatchVault balance did not change as expected after transferTransaction may have failed

Token Error Examples

// Handle losing position redemption attempt
if (error.code === 0x7005) {
  console.log('These shares did not win - payout is 0');
}

// Handle active market check
if (error.code === 0x7002) {
  console.log('A market already exists for this epoch');
  // Fetch and use existing market
}

Error Handling Best Practices

TypeScript Error Handler

function handleSeesawError(error: any): string {
  const code = error.code || error.error?.code;

  const errorMessages: Record<number, string> = {
    0x1001: 'Market not found - it may not be created yet',
    0x1003: 'Invalid market state for this operation',
    0x1005: 'Trading has ended for this market',
    0x2004: 'Oracle price is stale - try again shortly',
    0x3002: 'Insufficient USDC balance for this order',
    0x3003: 'Insufficient shares to sell',
    0x3006: 'PostOnly order would match - adjust price',
    // Add more as needed
  };

  return errorMessages[code] || `Unknown error: ${code}`;
}

Retry Logic

async function withRetry<T>(
  fn: () => Promise<T>,
  options: { maxRetries: number; retryableErrors: number[] }
): Promise<T> {
  let lastError: any;

  for (let i = 0; i < options.maxRetries; i++) {
    try {
      return await fn();
    } catch (e: any) {
      lastError = e;

      if (!options.retryableErrors.includes(e.code)) {
        throw e;
      }

      await sleep(1000 * Math.pow(2, i));
    }
  }

  throw lastError;
}

// Use with oracle errors
await withRetry(() => snapshotPrice(market), {
  maxRetries: 5,
  retryableErrors: [0x2004], // StaleOracle
});

Error Code Quick Reference

MARKET (0x10xx)           ORACLE (0x20xx)           ORDER (0x30xx)
├─ 0x1001 NotFound        ├─ 0x2001 InvalidOwner    ├─ 0x3001 InvalidQty
├─ 0x1002 Exists          ├─ 0x2002 InvalidFeed     ├─ 0x3002 NoCollateral
├─ 0x1003 InvalidState    ├─ 0x2003 Mismatch        ├─ 0x3003 NoShares
├─ 0x1004 NotStarted      ├─ 0x2004 Stale           ├─ 0x3004 BookFull
├─ 0x1005 Ended           ├─ 0x2005 InvalidPrice    ├─ 0x3005 NotFound
├─ 0x1006 Snapshotted     ├─ 0x2006 WideConf        ├─ 0x3006 WouldCross
├─ 0x1007 Resolved        ├─ 0x2007 NotTrading      ├─ 0x3007 Settled
├─ 0x1008 NotResolved     └─ 0x2008 FeedIdMismatch  ├─ 0x3008 NoPosition
├─ 0x1009 Closed                                    ├─ 0x3009 PriceLow
├─ 0x100A Expired         MATH (0x40xx)             ├─ 0x300A PriceHigh
├─ 0x100B TooEarly        └─ 0x4001 Overflow        └─ 0x300B CollateralLow
├─ 0x100C EpochNotStart
├─ 0x100D EpochNotEnd     ACCOUNT (0x50xx)          POSITION (0x60xx)
├─ 0x100E NotOwner        ├─ 0x5001 InvalidType     ├─ 0x6001 LimitExceeded
└─ 0x100F PositionsLeft   ├─ 0x5002 InvalidOwner    └─ 0x6002 Paused
                          ├─ 0x5003 InvalidPDA
                          ├─ 0x5004 Initialized     TOKEN (0x70xx)
                          ├─ 0x5005 NoRent          ├─ 0x7001 NotImpl
                          ├─ 0x5006 Insolvent       ├─ 0x7002 ActiveExists
                          └─ 0x5007 IdOverflow      ├─ 0x7003 CantExpire
                                                    ├─ 0x7004 InvalidToken
                                                    ├─ 0x7005 InvalidRedeem
                                                    └─ 0x7006 VaultMismatch

Next Steps