# Errors \[VaultKit 2.1 error classes, stable codes, diagnostics, and retry guidance.]

Every SDK error extends `ShieldError` and carries a stable `code`. `NewtonShieldError` is retained as a deprecated alias.

```typescript
import { isShieldError, ShieldError } from '@newton-xyz/vaultkit'

try {
  await operation()
} catch (error) {
  if (isShieldError(error)) {
    console.error(error.code, error.message, error.cause)
  }
}
```

## Error Classes

| Class | Code | Retry guidance |
| --- | --- | --- |
| `PolicyDeniedError` | `policy_denied` | Do not retry unchanged input. Rebuild against current state or accept the denial. |
| `PolicyNotDeniedError` | `policy_not_denied` | `assertIntentBlocked(...)` received an allowed intent; supply a genuinely noncompliant intent. |
| `NotApprovedDelegateError` | `not_approved_delegate` | Authorize the wallet or use an approved wallet. |
| `NewtonTaskEvaluationError` | `newton_task_evaluation_failed` | Inspect `operator_errors[]`; retry only transient operator failures. |
| `AttestationTimeoutError` | `attestation_timeout` | Retry with a fresh task after backoff. |
| `GatewayError` | `gateway_error` | Transport umbrella; inspect the subtype and status. |
| `GatewayHttpError` | `gateway_http_error` | Retry 5xx; fix authentication or request errors for 4xx. |
| `GatewayRpcError` | `gateway_rpc_error` | Depends on the JSON-RPC code. |
| `GatewayTimeoutError` | `gateway_timeout` | Retry with backoff. |
| `RpcReadError` | `rpc_read_error` | Retry against a healthier RPC endpoint. This class is emitted only for reads proven to have failed for a transport reason. |
| `PolicyMismatchError` | `policy_mismatch` | Reconcile the expected policy, module set, CIDs, or params. |
| `ParamMismatchError` | `param_mismatch` | Reconcile the expected and stored params. |
| `InvalidConfigurationError` | `invalid_configuration` | Fix the caller configuration. |
| `ExistingCloneVersionError` | `existing_clone_version` | Choose the intended existing version or a genuinely new version. |
| `ShieldDeploymentNotFoundError` | `shield_deployment_not_found` | The chain is supported but that environment has no recorded deployment. |
| `UnsupportedChainError` | `unsupported_chain` | Select a supported chain. |
| `ConcurrentIntentError` | `concurrent_intent` | Wait for the in-flight call; serialize calls per client. |
| `ExtendCollisionError` | `extend_collision` | Remove or rename the colliding extension. |
| `IntentConfigurationError` | `intent_configuration` | Fix malformed intent inputs. |
| `IntentMismatchError` | `intent_mismatch` | Rebuild and re-evaluate; never submit mismatched task data. |
| `TransactionFailedError` | `transaction_failed` | Inspect `cause`; retry only if the underlying failure is transient. |
| `ShieldExecutionError` | `shield_execution` | Inspect the decoded revert before deciding. |

## RPC Reads: Transport vs Terminal

VaultKit classifies chain-read failures before exposing them. Proven network, timeout, socket, HTTP, or transient JSON-RPC failures become `RpcReadError`. Contract reverts, zero data, decode failures, and configuration mismatches remain terminal errors such as `InvalidConfigurationError` or `PolicyMismatchError`.

```typescript
try {
  await createShield(config)
} catch (error) {
  if (error instanceof RpcReadError) {
    console.error(`Transient read failed: ${error.read}`)
    // Retry against a healthy endpoint with backoff.
  }
}
```

A chainless `publicClient` is probed with `getChainId()`. A terminal chain mismatch is not safe to retry.

## Failed Evaluation Diagnostics

The top-level task summary can say that quorum was not reached even when operators returned deterministic policy failures. Inspect the raw gateway result's `operator_errors[]` before retrying:

```json
{
  "error_code": -32002,
  "message": "Policy evaluation failed: params schema validation failed",
  "operator_address": "0x...",
  "retryable": false,
  "timestamp": "2026-07-01T00:00:00Z"
}
```

`retryable: false` usually indicates invalid params, missing secrets, schema mismatch, or deterministic oracle evaluation. Repeating the same request will not repair it.

## Blocked-Intent Errors

`assertIntentBlocked(...)` distinguishes three important outcomes:

* A confirmed `InvalidAttestation` simulation returns `{ blocked: true, taskId, reason }`.
* An allowed action throws `PolicyNotDeniedError`.
* An unauthorized wallet throws `NotApprovedDelegateError` before the policy-block assertion, so an authorization failure is never mislabeled as policy enforcement.

For raw simulation tooling, `decodeShieldRevertName(error)` returns the decoded custom-error name when available.

## Retry Pattern

```typescript
import {
  AttestationTimeoutError,
  GatewayTimeoutError,
  RpcReadError,
} from '@newton-xyz/vaultkit'

async function retryable<T>(operation: () => Promise<T>, attempts = 3) {
  let lastError: unknown

  for (let attempt = 0; attempt < attempts; attempt++) {
    try {
      return await operation()
    } catch (error) {
      const canRetry =
        error instanceof AttestationTimeoutError ||
        error instanceof GatewayTimeoutError ||
        error instanceof RpcReadError

      if (!canRetry) throw error

      lastError = error
      await new Promise((resolve) =>
        setTimeout(resolve, 1_000 * 2 ** attempt),
      )
    }
  }

  throw lastError
}
```

Always log `code`, `message`, and `cause`. For decoded execution failures, also log the error name and arguments.
