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

# Error Handling

> Common errors and troubleshooting for @loyal-labs/private-transactions

<img className="block dark:hidden" src="https://mintcdn.com/loyal/DWVryRcChq6727Ic/resources/private-txn/errors-light.png?fit=max&auto=format&n=DWVryRcChq6727Ic&q=85&s=0985c5a70b319795a65d9a17e5b90d76" width="1500" height="600" data-path="resources/private-txn/errors-light.png" />

<img className="hidden dark:block" src="https://mintcdn.com/loyal/DWVryRcChq6727Ic/resources/private-txn/errors-dark.png?fit=max&auto=format&n=DWVryRcChq6727Ic&q=85&s=25402dd028525253ec999c627680f7f4" width="1500" height="600" data-path="resources/private-txn/errors-dark.png" />

## SDK Validation Errors

### Username validation

Triggered before transaction submission when username input is invalid:

* `"Username must be between 5 and 32 characters"`
* `"Username can only contain lowercase alphanumeric characters and underscores"`

### Delegation state errors

The SDK guards execution context for every operation:

* `"Account is delegated to ER: ..."` — a base-layer operation (`modifyBalance`, `createPermission`, `initializeDeposit`) was attempted on a delegated account. Undelegate first.
* `"Account is not delegated to ER: ..."` — a PER operation (`transferDeposit`, `transferToUsernameDeposit`, `claimUsernameDepositToDeposit`) was attempted before delegation. Delegate first.
* `"Account is delegated on wrong validator: ..."` — delegation authority does not match the expected `ER_VALIDATOR`.

### Permission idempotency

`createPermission` and `createUsernamePermission` are idempotent:

* Return `null` when the permission account already exists.
* May return `"permission-exists"` if an `already in use` race condition is observed.

### PER auth / signer capability errors

When auth is needed on hosted PER endpoints, the SDK may throw:

* `"Wallet does not support signMessage, required for PER auth"`
* `"AnchorProvider wallet does not support signMessage, required for PER auth"`

Pass a signer with `signMessage` support, or provide an explicit `authToken` in `fromConfig`.

## On-Chain Program Errors

These are emitted by the `telegram-private-transfer` program (`97FzQdWi26mFNR21AbQNg4KqofiCLqQydQfAvRQMcXhV`):

| Error Code            | Message                  | When                                                                                                            |
| --------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------- |
| `Unauthorized`        | `"Unauthorized"`         | Session auth fails, permission mismatch, or signer does not match deposit owner                                 |
| `Overflow`            | `"Overflow"`             | Amount addition overflows `u64` during deposit or claim                                                         |
| `InvalidMint`         | `"Invalid Mint"`         | Token mint mismatch between accounts                                                                            |
| `InsufficientVault`   | `"Insufficient Vault"`   | Vault does not hold enough tokens for withdrawal                                                                |
| `InsufficientDeposit` | `"Insufficient Deposit"` | Deposit or username deposit `amount` is less than the requested withdrawal/transfer                             |
| `NotVerified`         | `"Not Verified"`         | Telegram session is not verified — `store` + `verify_telegram_init_data` must complete first                    |
| `ExpiredSignature`    | `"Expired Signature"`    | Verification signature has expired                                                                              |
| `Replay`              | `"Replay"`               | Replay attack detected during verification                                                                      |
| `InvalidEd25519`      | `"Invalid Ed25519"`      | Ed25519 signature verification failed                                                                           |
| `InvalidUsername`     | `"Invalid Username"`     | Username fails validation (length or character set), or username in session does not match the username deposit |
| `InvalidRecipient`    | `"Invalid Recipient"`    | Recipient wallet does not match the expected claim target                                                       |
| `InvalidDepositor`    | `"Invalid Depositor"`    | Depositor validation failed                                                                                     |

## Troubleshooting Checklist

1. **Delegation state mismatch** — confirm the deposit is in the correct state for the method:
   * Base-layer ops (`modifyBalance`, `createPermission`, `initializeDeposit`): account must **not** be delegated
   * PER ops (`transferDeposit`, `transferToUsernameDeposit`, `claimUsernameDepositToDeposit`): account **must** be delegated

2. **Telegram session not verified** — ensure the full verification flow completed:
   * `store(validationBytes)` on the `telegram-verification` program
   * `verify_telegram_init_data()` with Ed25519 instruction
   * Check `session.verified === true` before calling claim or username permission methods

3. **Token mint alignment** — confirm all accounts (deposit, username deposit, vault, user ATA) use the same token mint

4. **PER endpoint wiring** — for hosted PER (`devnet-tee.magicblock.app`):
   * Verify `ephemeralRpcEndpoint` and `ephemeralWsEndpoint` are set
   * Ensure signer supports `signMessage` for auth token acquisition, or pass `authToken` explicitly

5. **Insufficient balance** — `InsufficientDeposit` means the deposit's `amount` is less than what you're trying to transfer or withdraw. Check with `getBaseDeposit()` or `getEphemeralDeposit()`

6. **Username validation** — usernames must be 5–32 characters, only `[a-zA-Z0-9_]`. This is validated both client-side (SDK) and on-chain
