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

# Error Handling

> Common errors, error codes, and handling strategies

# Error Handling

This guide covers common errors you'll encounter when integrating with Kroko DEX and how to handle them.

## API Errors

When an API call fails, the response includes an error message:

```json theme={null}
{
  "error": "No route found"
}
```

| Error                     | Cause                                | Solution                                       |
| ------------------------- | ------------------------------------ | ---------------------------------------------- |
| `No route found`          | No liquidity path between the tokens | Verify token addresses; check that pools exist |
| `Invalid token address`   | Malformed address                    | Use checksummed or lowercase hex addresses     |
| `Amount must be positive` | Zero or negative amount              | Provide a valid positive amount string         |
| `Invalid tradeType`       | tradeType is not 0 or 1              | Use `0` (Exact Input) or `1` (Exact Output)    |

## Transaction Errors

### On-Chain Reverts

These errors occur when the transaction is submitted but reverts on-chain:

| Error                   | Cause                                  | Solution                                               |
| ----------------------- | -------------------------------------- | ------------------------------------------------------ |
| `TRANSFER_FROM_FAILED`  | Insufficient token approval or balance | Check Permit2 approval (Steps 1 & 2) and token balance |
| `EXPIRED`               | Transaction deadline exceeded          | Use a longer deadline or resubmit quickly              |
| `V3_INVALID_AMOUNT_OUT` | Output below `minAmountOut` (slippage) | Increase slippage tolerance or reduce trade size       |
| `INSUFFICIENT_ETH`      | Not enough native KAS sent as `value`  | Ensure `value` matches the required input amount       |

### Wallet Errors

```typescript theme={null}
try {
  const tx = await signer.sendTransaction(swapData);
  await tx.wait();
} catch (error) {
  if (error.code === 'ACTION_REJECTED' || error.code === 4001) {
    // User rejected the transaction in their wallet
    console.log('Transaction cancelled by user');
    return;
  }

  if (error.code === 'ERR_NETWORK') {
    // Network connectivity issue
    console.log('Network error — check your connection');
    return;
  }

  // Other errors
  console.error('Transaction failed:', error.message);
}
```

## Approval Errors

Common issues with the approval flow:

| Symptom                                  | Cause                                    | Fix                                                    |
| ---------------------------------------- | ---------------------------------------- | ------------------------------------------------------ |
| Swap fails after successful approval     | Approved wrong contract                  | Ensure Step 1 approves Permit2 (not Universal Router)  |
| Permit2 approval succeeds but swap fails | Permit2 sub-approval expired             | Check expiration and re-approve if needed              |
| "Insufficient allowance"                 | Amount approved is less than swap amount | Approve `MaxUint256` (Step 1) or `MaxUint160` (Step 2) |

### Checking Approval State

```typescript theme={null}
// Check ERC-20 → Permit2 approval
const tokenAllowance = await token.allowance(userAddress, PERMIT2);
console.log('Token → Permit2:', tokenAllowance.toString());

// Check Permit2 → Universal Router approval
const [amount, expiration] = await permit2.allowance(
  userAddress, tokenAddress, UNIVERSAL_ROUTER
);
console.log('Permit2 → Router:', amount.toString());
console.log('Expiration:', new Date(Number(expiration) * 1000));
```

## Best Practices

### Pre-flight Checks

Before executing a swap, verify:

```typescript theme={null}
async function preflightCheck(userAddress, tokenIn, amountIn) {
  // 1. Check balance
  const balance = await token.balanceOf(userAddress);
  if (balance < amountIn) {
    throw new Error(`Insufficient balance: have ${balance}, need ${amountIn}`);
  }

  // 2. Check ERC-20 approval to Permit2
  const allowance = await token.allowance(userAddress, PERMIT2);
  if (allowance < amountIn) {
    return { needsApproval: 'token' };
  }

  // 3. Check Permit2 sub-approval
  const [amount, expiration] = await permit2.allowance(
    userAddress, tokenIn, UNIVERSAL_ROUTER
  );
  if (amount < amountIn || expiration < Math.floor(Date.now() / 1000)) {
    return { needsApproval: 'permit2' };
  }

  return { needsApproval: null };
}
```

### Retry Strategy

* **API errors**: Safe to retry immediately (transient network issues)
* **On-chain reverts**: Do NOT retry blindly — diagnose the cause first
* **User rejection**: Do not retry — wait for user to initiate again
* **Slippage errors**: Re-fetch the quote (price may have changed) and retry with fresh calldata
