# Error Codes

The `KsusdError` enum lists every program-level error the ksUSD vault can return. Each maps to an Anchor exit code (starting at `0x1770`; the IDL has the exact codes).

> Source: [`programs/keystone-finance/src/errors.rs`](https://github.com/kamwithak/keystone-contracts/blob/main/programs/keystone-finance/src/errors.rs)

***

## General

| Variant         | Meaning                           | Common cause                                                                                                 |
| --------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `Unauthorized`  | Admin / keeper signature required | A non-admin called a privileged instruction, or a non-keeper called strategy when `authorized_keeper` is set |
| `Paused`        | Vault is paused                   | Admin paused; only `withdraw_instant` and `claim_wind_down` still work                                       |
| `MathOverflow`  | Math overflow                     | Bad input or share-price edge case                                                                           |
| `InvalidParams` | Invalid configuration             | Param outside allowed range (e.g. `perf_fee_bps > 5000`) or remaining-accounts split overflow                |

## Deposit / withdraw

| Variant                       | Meaning                                                                                       |
| ----------------------------- | --------------------------------------------------------------------------------------------- |
| `ZeroDeposit`                 | `usdc_amount == 0`                                                                            |
| `DepositCapExceeded`          | New deposit would push `cached_nav_usdc` past `deposit_cap_usdc`                              |
| `InsufficientShares`          | User's ksUSD ATA holds less than requested                                                    |
| `InsufficientLiquidityBuffer` | Vault doesn't have enough idle USDC for instant withdrawal — use `request_withdrawal` instead |
| `SlippageExceeded`            | Realized swap slippage exceeds `max_swap_slippage_bps`                                        |

## Position state

| Variant                  | Meaning                                                                                |
| ------------------------ | -------------------------------------------------------------------------------------- |
| `PositionAlreadyOpen`    | Calling `open_position` / `open_reverse` while a position is already open              |
| `PositionNotOpen`        | Calling `close_position` / `close_reverse` / `emergency_close` with no active position |
| `FundingThresholdNotMet` | Keeper attempted to open a mode whose funding-rate threshold wasn't cleared            |
| `MinDwellNotElapsed`     | Less than `min_dwell_seconds` since last mode change                                   |

## External venues

| Variant             | Meaning                                     |
| ------------------- | ------------------------------------------- |
| `DriftCpiFailed`    | The Drift Perps CPI returned an error       |
| `KaminoCpiFailed`   | The Kamino KLend CPI returned an error      |
| `JupiterSwapFailed` | The Jupiter V6 route CPI failed             |
| `InvalidMint`       | Account constraint mismatched expected mint |

## Oracle

| Variant                    | Meaning                                              |
| -------------------------- | ---------------------------------------------------- |
| `StaleOracle`              | Pyth price update older than the staleness threshold |
| `OracleConfidenceExceeded` | Pyth confidence interval > 2% of the price           |

## Reverse basis

| Variant                  | Meaning                                              |
| ------------------------ | ---------------------------------------------------- |
| `ReverseBasisNotEnabled` | `open_reverse` called without prior `enable_reverse` |
| `KaminoLtvExceeded`      | Requested jitoSOL borrow would exceed Kamino LTV     |

## Risk

| Variant                 | Meaning                                                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| `EmergencyDrawdown`     | NAV dropped more than `emergency_close_dd_bps` from peak                                                   |
| `LstDepeg`              | jitoSOL price deviated beyond `lst_depeg_bps` — `settle` auto-pauses                                       |
| `DrawdownTriggerLatent` | Drawdown trigger requires N consecutive settles below threshold (set by `consecutive_dd_settles_required`) |
| `FundingSignalStale`    | Smoothed funding signal older than `funding_max_staleness_seconds`; run `settle` first                     |
| `FundingRateInsane`     | Funding rate sanity check failed (absurd value reported by Drift — most likely an oracle / venue incident) |

## Withdrawal queue

| Variant                      | Meaning                                                                               |
| ---------------------------- | ------------------------------------------------------------------------------------- |
| `WithdrawalAlreadyProcessed` | `process_withdrawal` called on a request that's already settled                       |
| `WithdrawalUserMismatch`     | Recorded `user_usdc_account` doesn't match the passed destination                     |
| `WithdrawalNotNextInQueue`   | Queued requests must be processed strictly in FIFO order — pass the next `request_id` |
| `BelowMinRequestShares`      | `request_withdrawal` shares below `min_request_shares`                                |
| `QueueCapExceeded`           | Queue would exceed `max_pending_queue_usdc`                                           |

## NAV attestation

| Variant               | Meaning                                                            |
| --------------------- | ------------------------------------------------------------------ |
| `NavChangeExceedsCap` | `attest_nav` delta exceeds `max_nav_change_bps_per_hour`           |
| `NavStale`            | NAV stale — `settle` / `attest_nav` required before this operation |

## Lending

| Variant                 | Meaning                                                                 |
| ----------------------- | ----------------------------------------------------------------------- |
| `LendingNotEnabled`     | `lend_idle_usdc` / `lend_reserve` called without prior `enable_lending` |
| `LendingBreachesBuffer` | Lending more would drop idle USDC below `liquidity_buffer_target`       |

## Wind-down / admin transfer

| Variant           | Meaning                                                             |
| ----------------- | ------------------------------------------------------------------- |
| `WindDownActive`  | Vault is in wind-down — new deposits / positions / un-pause blocked |
| `NoPendingAdmin`  | `accept_admin` called when no pending admin is set                  |
| `NotPendingAdmin` | `accept_admin` signer doesn't match `pending_admin`                 |

## Bootstrap

| Variant                 | Meaning                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------- |
| `BootstrapResidualUsdc` | Vault USDC ATA must be empty before the first deposit (prevents dilution griefing) |

***

## Reading errors from a client

```ts
try {
  await program.methods.withdrawInstant(new BN(amount)).accountsStrict({...}).rpc();
} catch (e: any) {
  // AnchorError exposes .error.errorCode.code (string) and .error.errorMessage
  if (e.error?.errorCode?.code === "InsufficientLiquidityBuffer") {
    // fall back to request_withdrawal
  }
  throw e;
}
```

In raw transaction logs the error appears as e.g. `AnchorError caused by account: ... InsufficientLiquidityBuffer.` followed by the exit code.

***

## Related

* [Instructions](/for-developers/instructions.md) · [Account structure](/for-developers/accounts.md) · [Events](/for-developers/events.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keystonefi.xyz/for-developers/errors.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
