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

> ## Agent Instructions
> Before reading these docs, install the Circle Skill for Arc to get pre-loaded context: use-arc (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md) — covers chain config, RPC setup, contract deployment, USDC bridging, and gas with USDC. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills.
> USDC is the gas token. Arc uses USDC for gas fees, not ETH. Configure gas payment in USDC when submitting transactions.
> Read EVM differences before writing Arc code. Arc targets the Osaka EVM baseline. Most contracts deploy unchanged, but several runtime behaviors diverge from Ethereum: USDC uses 18 decimals natively (not 6), the system emitter `0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE` logs all USDC Transfer events, the mempool enforces a 20 Gwei `maxFeePerGas` floor, blocklist reverts consume gas without a receipt, and `address(0)` sends revert rather than succeed. https://docs.arc.io/arc/references/evm-differences.md is the canonical reference for all Arc-specific runtime behaviors. Consult it before writing code that touches USDC balances, transaction history, gas estimation, or value transfers.
> Sub-second finality. Transactions are final in under 1 second. No need to wait for multiple block confirmations.
> Use App Kits for multichain payment and liquidity capabilities. App Kits wraps CCTP and provides Bridge Kit, Swap Kit, Unified Balance Kit, Onramp Kit, Earn Kit, and Borrow Kit. Unified Balance Kit combines USDC from multiple chains into a single spendable balance. Earn Kit integrates earn opportunities into your app. Borrow Kit lets users borrow USDC against cirBTC collateral on Arc.
> Use Arc Foundry for contract development. Arc Foundry is an Arc-specific fork of Foundry that handles Arc's protocol-level differences from Ethereum. It provides arc-forge, arc-cast, and arc-anvil. Install it before deploying contracts: https://docs.arc.io/arc/tutorials/install-arc-foundry.md.
> Arc is available on both Testnet and Mainnet. See https://docs.arc.io/arc/references/connect-to-arc.md for RPC endpoints and https://faucet.circle.com for testnet tokens.
> Always check Contract Addresses: https://docs.arc.io/arc/references/contract-addresses.md
> Building beyond Arc? Circle offers skills for the full platform: use-usdc (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md), use-circle-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md), use-developer-controlled-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md), use-user-controlled-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md), use-modular-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md), use-gateway (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md), use-smart-contract-platform (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md). Full Circle developer docs: https://developers.circle.com/llms.txt.

# Swap error handling

> Catch and classify Swap errors using KitError fields, see common error codes, and resolve simulation failures on Arc testnet.

Errors the App Kit SDK throws for Swap are `KitError` instances, exported from
`@circle-fin/app-kit`. Its structured fields let you branch on the failure type
instead of parsing message strings. Errors surface from
[`kit.estimateSwap`](https://docs.arc.io/app-kit/references/sdk-reference#estimateswap-params) and
[`kit.swap`](https://docs.arc.io/app-kit/references/sdk-reference#swap-params).

## `KitError` fields

| Field | Description |
| - | - |
| `code` | Numeric identifier (for example, `5002`). |
| `name` | Stable string identifier for exact matching, logging, and telemetry. |
| `type` | Classifies the failure (see [Error types](#error-types)). |
| `recoverability` | `FATAL` (don't retry) or `RETRYABLE` (back off and retry). `RESUMABLE` is defined on `KitError` but not currently used by Swap errors. |
| `message` | Human-readable diagnostic. Not suitable for end-user display without review. |
| `cause` | The underlying error, if one was wrapped. |

Check `code` or `name` for specific handling, `type` for handling a whole
category, and `recoverability` to decide whether to retry.

## Error types

| Type | Origin | Typical recoverability |
| - | - | - |
| `INPUT` | Parameter validation, unsupported blockchain or token. | `FATAL` |
| `ONCHAIN` | Swap execution simulation or transaction reverted onchain. | `FATAL` |
| `BALANCE` | Insufficient token, gas, or allowance (surfaced from the wallet adapter). | `FATAL` |
| `RPC` | Blockchain RPC issues during execution (surfaced from the wallet adapter). | `RETRYABLE` |
| `NETWORK` | Connectivity or timeout reaching the Swap service. | `RETRYABLE` |
| `RATE_LIMIT` | Request throttled (HTTP 429). | `RETRYABLE` |
| `SERVICE` | Swap service backend failure. | `RETRYABLE` |
| `LIQUIDITY` | The routing provider can't fill the requested size right now. | `RETRYABLE` |
| `UNKNOWN` | Unrecognized error. | `FATAL` |

## Common error codes

| Code | Name | Type | When it fires |
| - | - | - | - |
| `1003` | `INPUT_UNSUPPORTED_ROUTE` | `INPUT` | No route exists for the token pair, blockchains, and amount. See [No route available](#no-route-available). |
| `1009` | `INPUT_SLIPPAGE_CONSTRAINT_NOT_MET` | `INPUT` | A route exists but not within the slippage tolerance or stop limit. Raise `slippageBps` or adjust `stopLimit`. |
| `1013` | `INPUT_AMOUNT_OUT_OF_RANGE` | `INPUT` | The amount is outside the routing provider's minimum or maximum. `cause.trace` includes `minAmount` or `maxAmount`. |
| `1098` | `INPUT_VALIDATION_FAILED` | `INPUT` | Swap parameters failed validation. Fix the inputs; retrying unchanged won't help. |
| `5001` | `ONCHAIN_TRANSACTION_REVERTED` | `ONCHAIN` | The swap transaction reverted after submission. |
| `5002` | `ONCHAIN_SIMULATION_FAILED` | `ONCHAIN` | The swap execution simulation reverted onchain. See [Simulation failures on Arc testnet](#simulation-failures-on-arc-testnet). |
| `6001` | `LIQUIDITY_INSUFFICIENT` | `LIQUIDITY` | A route exists, but the routing provider can't fill the requested size right now. Reduce the amount or try again later. |

## Handling errors

Catch a `KitError` and branch on `code`, `type`, and `recoverability`:

```typescript TypeScript theme={null}
import {
  isKitError,
  isRetryableError,
  getErrorCode,
} from "@circle-fin/app-kit";

try {
  const result = await kit.swap({
    from: { adapter, chain: "Arc_Testnet" },
    tokenIn: "USDC",
    tokenOut: "EURC",
    amountIn: "1.00",
  });
} catch (err) {
  if (isKitError(err)) {
    const code = getErrorCode(err);
    if (code === 1009 || code === 5001 || code === 5002) {
      // Price moved past the tolerance or the swap reverted: raise slippageBps. See below.
      return retryWithHigherSlippage();
    }
    if (err.type === "LIQUIDITY") {
      // Retrying the same size won't help until liquidity returns
      return promptForSmallerAmount();
    }
    if (isRetryableError(err)) {
      // Rate limits, network, and service failures: back off and retry
      return scheduleRetry();
    }
    if (err.type === "INPUT") {
      // `message` is a diagnostic — review it before showing it to end users
      console.error(`Swap input error: ${err.message}`);
      return;
    }
  }
  throw err;
}
```

## Simulation failures on Arc testnet

Because Arc testnet liquidity is thin,
[`kit.estimateSwap`](https://docs.arc.io/app-kit/references/sdk-reference#estimateswap-params) can
succeed while the swap itself fails with one of these errors:

* `INPUT_SLIPPAGE_CONSTRAINT_NOT_MET` (`1009`) when the route is quoted.
* `ONCHAIN_SIMULATION_FAILED` (`5002`) when `kit.swap` reverts during onchain
  simulation.
* `ONCHAIN_TRANSACTION_REVERTED` (`5001`) after the transaction is submitted.

To resolve the failure, raise the slippage tolerance above the 300 bps default
(for example, `1000` bps):

```typescript TypeScript theme={null}
const result = await kit.swap({
  from: { adapter, chain: "Arc_Testnet" },
  tokenIn: "USDC",
  tokenOut: "EURC",
  amountIn: "1.00",
  config: {
    slippageBps: 1000, // Raise the tolerance above the 300 bps default
  },
});
```

To set a stop limit instead of a slippage tolerance, see
[Set slippage tolerance or stop limit](https://docs.arc.io/app-kit/tutorials/swap/set-slippage-tolerance-or-stop-limit.md).

## No route available

Routing failures surface in three ways:

* `INPUT_UNSUPPORTED_ROUTE` (`1003`): the routing layer found no route for the
  token pair, blockchains, and amount you requested. Change the amount or pick a
  different token pair, since retrying the same request won't help.
* `INPUT_SLIPPAGE_CONSTRAINT_NOT_MET` (`1009`): a route exists but not within
  your slippage tolerance or stop limit. Raise `slippageBps` or adjust
  `stopLimit`.
* "No quotes available": a message from the routing provider itself, not the
  SDK, so you only see it when calling the provider's API directly. This isn't a
  supported integration path, and direct provider calls are rate limited. Route
  quotes through `kit.estimateSwap`. If you're hitting rate limits through the
  SDK itself, pass a [Circle API key](https://docs.arc.io/app-kit/swap.md#api-key) in the swap config.
