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

# Error Handling

> Handle simulation errors and validation failures in Shield API.

export const date_0 = "2026-04-07"

## HTTP Status Codes

| Status | Meaning           | When It Occurs                                                                            |
| ------ | ----------------- | ----------------------------------------------------------------------------------------- |
| `200`  | Request processed | Simulation or validation completed. Check `result.status` for simulation success/failure. |
| `400`  | Bad request       | Invalid parameters, missing required fields, or malformed request body.                   |
| `401`  | Unauthorized      | Missing or invalid API key.                                                               |
| `404`  | Not found         | Simulation ID not found or expired (validate endpoint only).                              |
| `429`  | Rate limited      | Too many requests. Back off and retry.                                                    |
| `500`  | Internal error    | Server-side failure. Retry after a short delay.                                           |

## Simulation Errors

A `200` response from `/simulate` does **not** always mean the transaction would succeed on-chain. Check `result.status`:

```typescript theme={null}
const simulation = await fetch("https://shield.api.enso.build/api/v1/simulate", {
  method: "POST",
  headers: { "Authorization": `Bearer ${ENSO_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify(request),
}).then((res) => res.json());

if (simulation.result.status === "Success") {
  console.log("Predicted output:", simulation.result.amountOut);
  console.log("Gas estimate:", simulation.result.gas);
} else {
  console.error("Transaction would fail:", simulation.result.error);
}
```

### Common Simulation Failures

| Error Type      | Description                                   | How to Fix                                                                          |
| --------------- | --------------------------------------------- | ----------------------------------------------------------------------------------- |
| `CallFailed`    | The transaction call failed during simulation | Check that the sender has sufficient balance and the calldata is correct            |
| `CallReverted`  | The contract reverted the transaction         | Inspect the revert reason — often an insufficient allowance or failed require check |
| `DecodeError`   | Could not decode the transaction result       | Verify the `data` field contains valid calldata for the target contract             |
| `ProviderError` | RPC provider error during simulation          | Retry — this is usually transient                                                   |

## Validation Errors

### Simulation Not Found (404)

If the simulation has expired (after 5 minutes) or the ID is invalid:

```json theme={null}
{
  "statusCode": 404,
  "message": "Simulation a1b2c3d4-e5f6-7890-abcd-ef1234567890 not found or expired"
}
```

**Fix:** Re-simulate to get a fresh `simulationId`.

### Partial Check Failures

When `valid` is `false`, inspect the `checks` object to find which fields failed:

```typescript theme={null}
const validation = await validate(simulationId, transaction);

if (!validation.valid) {
  const failures = Object.entries(validation.checks)
    .filter(([, passed]) => !passed)
    .map(([field]) => field);

  console.error("Failed checks:", failures);
  // Re-simulate instead of retrying validation
}
```

## Rate Limiting

Shield enforces rate limits per API key. When you receive a `429` response, back off before retrying:

```typescript theme={null}
async function simulateWithRetry(request: SimulateRequest, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch("https://shield.api.enso.build/api/v1/simulate", {
      method: "POST",
      headers: { "Authorization": `Bearer ${ENSO_API_KEY}`, "Content-Type": "application/json" },
      body: JSON.stringify(request),
    });

    if (response.status === 429) {
      await new Promise((resolve) => setTimeout(resolve, 1000 * (attempt + 1)));
      continue;
    }

    return await response.json();
  }

  throw new Error("Rate limited after max retries");
}
```

<div className="text-right text-xs gray-200 font-semibold w-full" style={{marginTop: '0'}}>
  <p style={{
        color: "#b2b2b2"  
    }}>Updated {date_0}</p>
</div>
