> ## Documentation Index
> Fetch the complete documentation index at: https://docs.iris.credit/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Every failure mode is a dedicated class: what each error means and which layer throws it.

The SDK never throws a bare `Error`: every failure mode has a dedicated class, so handlers branch on `instanceof` instead of parsing messages. Two layers throw. Flow errors come from [`@iris-credit/iris-sdk`](https://www.npmjs.com/package/@iris-credit/iris-sdk): the local validation flows run when they are created, before anything is signed or sent. Entity errors come from [`@iris-credit/core-sdk`](https://www.npmjs.com/package/@iris-credit/core-sdk): the offline math mirroring the contract's own failure conditions, plus the registry lookups behind the fetchers.

```typescript theme={null}
import { QuoteExpiredError, UnhealthyDebtError } from "@iris-credit/iris-sdk";

try {
  const { buildTx, getRequirements } = iris.take({ userAddress, quote, quoteSignature, venueData });
} catch (error) {
  if (error instanceof QuoteExpiredError) {
    // The quote died in transit: request a fresh one.
  } else if (error instanceof UnhealthyDebtError) {
    // The venue moved under the quote: request a smaller one.
  } else throw error;
}
```

Most validation runs when the flow is created on the entity, as above. `buildTx` adds only the signature checks under [Requirements and signatures](#requirements-and-signatures).

## Flow errors

Thrown by the `client.iris.core(chainId)` flows while validating what the contract would reject. All are importable from the package root.

### Inputs and loan state

| Error                                | When it throws                                                             |
| ------------------------------------ | -------------------------------------------------------------------------- |
| `ZeroAddressError`                   | An address field the contract requires to be non-zero is the zero address  |
| `NegativeInputError`                 | An input that must be non-negative is negative                             |
| `NonPositiveInputError`              | An input that must be positive is zero or negative                         |
| `LoanNotCreatedError`                | The pod has no Iris loan: its loan struct is still zeroed                  |
| `LoanResolvedError`                  | The flow needs an open loan but the pod's loan is already resolved         |
| `LoanNotResolvedError`               | `escape` targets a loan whose bond requirement is still non-zero           |
| `NativeAmountOnNonWNativeAssetError` | `nativeAmount` funds an asset that is not the chain's wrapped native token |
| `NativeAmountExceedsCollateralError` | A take's `nativeAmount` exceeds the quote's collateral                     |
| `ClaimExceedsClaimableError`         | A claim exceeds the account's claimable balance for the token              |

### Quote validation

Thrown by [`take`](/sdk/transactions#take):

| Error                               | When it throws                                                                                       |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `QuoteExpiredError`                 | The quote's deadline has passed                                                                      |
| `QuoteOutOfBoundsError`             | A rate, duration or overdue field is outside the [protocol bounds](/sdk/entities#protocol-constants) |
| `NotMultipleOfBpError`              | `fixedRate` or `overdueRate` is not a whole multiple of `BP`                                         |
| `NotAllowedVenueError`              | The quote's `venueId` is not set in its `venueBitmap`                                                |
| `VenueMismatchError`                | The pre-fetched `venueData` is a view of a different venue than the quote opens                      |
| `UnhealthyDebtError`                | The quote's debt exceeds the venue's safe max borrow for its collateral                              |
| `SolverPermit2AssetMismatchError`   | The solver's Permit2 payload is signed for a token other than the quote's debt token                 |
| `SolverPermit2AmountBelowBondError` | The solver's Permit2 payload is signed for less than the quote's bond                                |
| `SolverPermit2ExpiredError`         | The solver's Permit2 payload carries an expired allowance or signature deadline                      |

### Withdrawal ceilings

| Error                      | When it throws                                                         |
| -------------------------- | ---------------------------------------------------------------------- |
| `UnhealthyCollateralError` | A collateral withdrawal exceeds the position's withdrawable collateral |
| `UnhealthyBondError`       | A bond withdrawal exceeds the position's withdrawable bond             |

### Requirements and signatures

Thrown while resolving requirements or consuming their signatures in `buildTx`:

| Error                                    | When it throws                                                                    |
| ---------------------------------------- | --------------------------------------------------------------------------------- |
| `AmbiguousRequirementSignaturesError`    | `buildTx` receives more than one signature of the same kind                       |
| `UnexpectedRequirementSignatureError`    | `buildTx` receives a signature kind the flow does not consume                     |
| `Permit2ExpirationMissingError`          | A Permit2 requirement signature is missing `args.expiration`                      |
| `DepositAmountMismatchError`             | A deposit's amount differs from the amount its permit or Permit2 signature covers |
| `DepositAssetMismatchError`              | A deposit's asset differs from the asset its permit or Permit2 signature covers   |
| `ApprovalAmountLessThanSpendAmountError` | An approval amount is smaller than the spend it must cover                        |
| `UnsupportedErc20ApprovalSpenderError`   | A requirement targets a spender other than the chain's general adapter or Permit2 |
| `InvalidSignatureError`                  | EIP-712 signature verification does not recover the expected signer               |

### Client checks

| Error                        | When it throws                                                                                                                              |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `AddressMismatchError`       | `userAddress` differs from the borrower or solver the flow requires, or the connected account differs from the required signer when signing |
| `ChainIdMismatchError`       | The client's chain differs from the chain the entity was created for                                                                        |
| `MissingClientPropertyError` | The client lacks a required property such as `account.address`                                                                              |

### Bundler encoding

The `BundlerErrors` namespace covers Bundler3 action encoding:

| Error                               | When it throws                                                                                  |
| ----------------------------------- | ----------------------------------------------------------------------------------------------- |
| `BundlerErrors.MissingSignature`    | An action that needs an offchain signature is encoded before the signature is attached          |
| `BundlerErrors.UnexpectedAction`    | An action is unsupported on the requested chain                                                 |
| `BundlerErrors.UnexpectedSignature` | An Iris authorization signature names a forbidden `authorized` account, such as Bundler3 itself |

## Entity errors

`@iris-credit/core-sdk` throws where the model itself cannot proceed. The `IrisCoreErrors` namespace mirrors the contract's failure conditions inside the offline math, so a transition that would revert onchain throws the matching class offline:

```typescript theme={null}
import { IrisCoreErrors } from "@iris-credit/core-sdk";
```

| Error                                        | When it throws                                                                                          |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `IrisCoreErrors.InvalidInterestAccrual`      | An accrual is requested for a timestamp before the position's `lastUpdate`                              |
| `IrisCoreErrors.InvalidVenueInterestAccrual` | A venue accrual is requested before a venue side's last update                                          |
| `IrisCoreErrors.InvalidVenueIndex`           | A venue index is behind the index the position last stored                                              |
| `IrisCoreErrors.UnknownVenuePrice`           | The venue price is unknown, so price-dependent math is underivable                                      |
| `IrisCoreErrors.InsufficientVenueCollateral` | A venue collateral withdrawal would leave the pod's venue position unhealthy                            |
| `IrisCoreErrors.InsufficientVenuePosition`   | A venue position would go negative                                                                      |
| `IrisCoreErrors.InsufficientVenueLiquidity`  | A venue borrow would exceed the market's available supply                                               |
| `IrisCoreErrors.UnexpectedPod`               | A position's loan or venue belongs to a different pod                                                   |
| `IrisCoreErrors.UnexpectedVenue`             | A venue is not the market the position is held on: id and market data both identify it                  |
| `IrisCoreErrors.HealthyLoan`                 | A liquidation is replayed before the loan's liquidation deadline                                        |
| `IrisCoreErrors.HealthyBond`                 | A bond liquidation is replayed while the bond is healthy                                                |
| `IrisCoreErrors.InsufficientCollateral`      | A collateral withdrawal would leave the loan undercollateralized                                        |
| `IrisCoreErrors.InsufficientBond`            | A bond withdrawal would leave the bond unhealthy                                                        |
| `IrisCoreErrors.LoanResolved`                | An operation requires an open loan but it is resolved                                                   |
| `IrisCoreErrors.NotAllowedVenue`             | A venue is not allowed by the loan's venue bitmap                                                       |
| `IrisCoreErrors.ZeroBondRequirement`         | A quote's [bond requirement](/sdk/entities#bond-requirements) computes to zero, making it unsubmittable |

### Registry lookups

| Error                          | When it throws                                                                               |
| ------------------------------ | -------------------------------------------------------------------------------------------- |
| `UnsupportedChainIdError`      | A chain id has no registered addresses or protocol configuration                             |
| `UnknownDataHashError`         | `getMarketData` is called with a `keccak256(data)` hash the chain's registry does not record |
| `UnsupportedVenueAdapterError` | A venue adapter has no offline rate model registered in the SDK                              |
| `UnsupportedAaveV3TokenError`  | A token has no Aave V3 reserve tokens registered in the SDK                                  |
