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

# Error Handling

> How to handle errors and failure modes when using LI.FI Composer, including API errors, transaction failures, and cross-chain edge cases.

This page covers the errors you may encounter when using Composer and how to handle them. Composer uses the same error system as the broader LI.FI API, and the errors documented here are contextualised for Composer-specific scenarios.

***

## API Errors (Quote/Route Request)

When requesting a Composer quote via `GET /quote` or `POST /advanced/routes`, the API may return errors. These follow the standard LI.FI error format:

1. **HTTP status code** (e.g., 200, 404, 429, 500)
2. **LI.FI error code** (numeric)
3. **Error message** (human-readable)

### Relevant API Error Codes

| Code   | Name                            | Composer Context                                                                                                                 |
| ------ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `1001` | `FailedToBuildTransactionError` | Composer could not build the transaction. The vault token may be invalid or the protocol may be temporarily unavailable.         |
| `1002` | `NoQuoteError`                  | No Composer route found. The vault token address may not be supported, or there's insufficient liquidity for the requested path. |
| `1004` | `NotProcessableError`           | The request cannot be processed. Check that all parameters are valid.                                                            |
| `1005` | `RateLimitError`                | Too many requests. Implement backoff and retry. See [Rate Limits](/api-reference/rate-limits).                                   |
| `1007` | `SlippageError`                 | Price impact exceeds slippage tolerance. Increase the `slippage` parameter or reduce the amount.                                 |
| `1009` | `TimeoutError`                  | Request timed out. Retry the request.                                                                                            |
| `1011` | `ValidationError`               | Invalid parameters. Check that `fromChain`, `toChain`, `fromToken`, `toToken`, and `fromAmount` are valid.                       |

For the complete list of API error codes, see [Error Codes](/api-reference/error-codes).

***

## Tool Errors

The API may also return tool-specific errors describing issues with the underlying protocols. These use the `ToolError` format:

```typescript theme={"system"}
interface ToolError {
  errorType: "NO_QUOTE";
  code: string;
  action: Action;
  tool: string;
  message: string;
}
```

### Relevant Tool Error Codes

| Code                      | Description                            | Composer Context                                                                                   |
| ------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `NO_POSSIBLE_ROUTE`       | No route found for this action         | The vault token may not be supported, or the source/destination chain combination is not available |
| `INSUFFICIENT_LIQUIDITY`  | The tool's liquidity is insufficient   | Not enough liquidity to complete the swap portion of the Composer flow                             |
| `TOOL_TIMEOUT`            | The third-party tool timed out         | The underlying protocol or DEX timed out. Retry the request.                                       |
| `AMOUNT_TOO_LOW`          | Amount is too low to transfer          | Increase `fromAmount`. Composer routes may have higher minimums due to multiple steps.             |
| `AMOUNT_TOO_HIGH`         | Amount exceeds available liquidity     | Reduce `fromAmount` or split into multiple transactions.                                           |
| `FEES_HIGHER_THAN_AMOUNT` | Fees exceed the transfer amount        | Increase `fromAmount` so it covers gas and protocol fees.                                          |
| `TOOL_SPECIFIC_ERROR`     | The third-party tool returned an error | The target protocol returned an error. Check that the vault is accepting deposits.                 |

### Example: Handling Tool Errors

```ts theme={"system"}
try {
  const quote = await axios.get("https://li.quest/v1/quote", { params });
} catch (error) {
  if (error.response?.data?.errors) {
    for (const toolError of error.response.data.errors) {
      console.error(`Tool: ${toolError.tool}`);
      console.error(`Code: ${toolError.code}`);
      console.error(`Message: ${toolError.message}`);

      switch (toolError.code) {
        case "NO_POSSIBLE_ROUTE":
          // Vault token may not be supported
          console.log(
            "Check that the toToken is a supported vault token address.",
          );
          break;
        case "INSUFFICIENT_LIQUIDITY":
          // Try a smaller amount
          console.log("Try reducing the fromAmount.");
          break;
        case "AMOUNT_TOO_LOW":
          // Increase the amount
          console.log("Increase the fromAmount.");
          break;
        case "TOOL_TIMEOUT":
          // Retry
          console.log("Retrying...");
          break;
      }
    }
  }
}
```

***

## Transaction Failures

### Pre-Execution Simulation Failure

Composer simulates the entire execution path before returning a quote. If simulation fails, the API returns an error **instead of** a transaction that would revert onchain. This protects users from wasting gas on failed transactions.

Common simulation failure causes:

* The vault is not accepting deposits (paused, full, or restricted)
* The token path involves incompatible tokens
* Insufficient liquidity in the swap path

### Onchain Transaction Revert

In rare cases, a transaction may revert onchain even after passing simulation (e.g., due to mempool front-running or rapid state changes between simulation and execution). If this happens:

1. The user's tokens remain in their wallet (for same-chain atomic transactions)
2. Gas fees for the reverted transaction are still consumed
3. Retry with a fresh quote to get updated simulation results

***

## Cross-Chain Failure Modes

Cross-chain Composer flows have two phases. Each phase is atomic within its chain, but the overall flow is eventually consistent.

### Status Values

Poll `GET /v1/status` to track cross-chain Composer transactions. The status values are:

| Status      | Description                                |
| ----------- | ------------------------------------------ |
| `NOT_FOUND` | Transaction doesn't exist or not yet mined |
| `INVALID`   | Hash is not tied to the requested tool     |
| `PENDING`   | Transfer is still in progress              |
| `DONE`      | Transaction completed successfully         |
| `FAILED`    | Transfer failed                            |

### Substatus Values

#### When Status is `PENDING`

| Substatus                      | Description                              |
| ------------------------------ | ---------------------------------------- |
| `WAIT_SOURCE_CONFIRMATIONS`    | Waiting for source chain confirmations   |
| `WAIT_DESTINATION_TRANSACTION` | Waiting for destination transaction      |
| `BRIDGE_NOT_AVAILABLE`         | Bridge API is unavailable                |
| `CHAIN_NOT_AVAILABLE`          | Source/destination chain RPC unavailable |
| `REFUND_IN_PROGRESS`           | Refund in progress (if supported)        |
| `UNKNOWN_ERROR`                | Status is indeterminate                  |

#### When Status is `DONE`

| Substatus   | Description                     |
| ----------- | ------------------------------- |
| `COMPLETED` | Transfer was successful         |
| `PARTIAL`   | Only partial transfer completed |
| `REFUNDED`  | Tokens were refunded            |

#### When Status is `FAILED`

| Substatus                       | Description                    |
| ------------------------------- | ------------------------------ |
| `NOT_PROCESSABLE_REFUND_NEEDED` | Cannot complete, refund needed |
| `OUT_OF_GAS`                    | Transaction ran out of gas     |
| `SLIPPAGE_EXCEEDED`             | Received amount too low        |
| `INSUFFICIENT_ALLOWANCE`        | Not enough token allowance     |
| `INSUFFICIENT_BALANCE`          | Not enough token balance       |
| `EXPIRED`                       | Transaction expired            |
| `UNKNOWN_ERROR`                 | Unknown or invalid state       |
| `REFUNDED`                      | Tokens were refunded           |

### Handling Cross-Chain Failures

```ts theme={"system"}
const status = await axios
  .get("https://li.quest/v1/status", {
    params: { txHash, fromChain, toChain },
  })
  .then((r) => r.data);

switch (status.status) {
  case "DONE":
    if (status.substatus === "COMPLETED") {
      console.log("Composer deposit completed successfully.");
    } else if (status.substatus === "PARTIAL") {
      console.log(
        "Partial completion: bridged tokens may be on destination chain but not deposited.",
      );
    } else if (status.substatus === "REFUNDED") {
      console.log("Tokens were refunded to source chain.");
    }
    break;

  case "FAILED":
    if (status.substatus === "SLIPPAGE_EXCEEDED") {
      console.log("Slippage exceeded. Retry with higher slippage tolerance.");
    } else if (status.substatus === "INSUFFICIENT_ALLOWANCE") {
      console.log("Insufficient allowance. Approve tokens before retrying.");
    } else if (status.substatus === "NOT_PROCESSABLE_REFUND_NEEDED") {
      console.log("Transfer cannot complete. Refund will be processed.");
    } else {
      console.error(
        "Transfer failed:",
        status.substatus,
        status.substatusMessage,
      );
    }
    break;

  case "PENDING":
    console.log("Still in progress:", status.substatus);
    break;
}
```

For the full status reference, see [Transaction Status Tracking](/introduction/user-flows-and-examples/status-tracking).

***

## Common Composer Issues

| Issue                        | Cause                                            | Resolution                                                                                |
| ---------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| No routes returned           | `toToken` is not a supported vault token address | Verify the address against the [Supported Protocols](/composer/protocols-and-chains) list |
| Simulation failed            | Vault is paused, full, or not accepting deposits | Check the protocol's status directly                                                      |
| Transaction reverted         | State changed between simulation and execution   | Retry with a fresh quote                                                                  |
| Cross-chain stuck in PENDING | Bridge is slow or congested                      | Wait and continue polling. Check the bridge's own status page if it remains stuck.        |
| Partial completion           | Bridge succeeded but destination action failed   | User has tokens on destination chain. They can retry the deposit directly.                |

***

## Related Pages

<CardGroup cols={2}>
  <Card title="Error Codes" icon="circle-exclamation" href="/api-reference/error-codes">
    Complete LI.FI API error code reference
  </Card>

  <Card title="Status Tracking" icon="signal" href="/introduction/user-flows-and-examples/status-tracking">
    Full status and substatus reference
  </Card>

  <Card title="API Parameters" icon="sliders" href="/composer/lifi-api/reference/api-parameters">
    Composer-specific API parameters
  </Card>

  <Card title="Limitations" icon="circle-info" href="/composer/lifi-api/reference/limitations">
    Current Composer limitations
  </Card>
</CardGroup>
