# Error codes

When a call fails, the package returns `{ok: false, error: '<code>'}` (or the raw
bridge returns `{success: false, error: '<code>'}`). Never show the raw code to the
player — translate it to a friendly message.

| Code | Meaning | What to do |
|---|---|---|
| `insufficient_coins` | Player doesn't have enough | Show a "need X more coins" message |
| `invalid_amount` | Amount ≤ 0, non-integer, or over the cap | Fix the call site |
| `invalid_reason` | Reason failed the regex / length check | Use `[a-z0-9_]+`, ≤ 64 chars |
| `invalid_data` | `saveProgress` data wasn't a JSON object | Pass a plain object |
| `data_too_large` | `saveProgress` payload > 100 KB | Compact your state; don't retry |
| `serialization_error` | Save data wasn't JSON-serialisable | Remove functions / circular refs |
| `save_failed` | Backend rejected the save | Transient — retry with backoff |
| `rate_limited` | Too many calls / earn cap hit | Back off and retry later |
| `forbidden` | Call wasn't for the signed-in player | Don't pass user ids; let the app own identity |
| `user_not_found` | No authenticated user | Fall back to offline mode |
| `network_error` | Request to the backend failed | Transient — retry with backoff |
| `internal_error` | Unexpected bridge error | Report to the Gamma team |
| `dispatch_error` | Bridge transport failed to send | Treat as `network_error` |
| `empty_response` | Bridge returned nothing | Treat as `network_error` |
| `timeout` | Bridge didn't respond in 30 s | Treat as `network_error` |
| `unknown_type` | Unknown message type (SDK/app mismatch) | Update your SDK / check the call |
| `no_transport` | Running outside the app, mock disabled | Use [`isInApp`](./guides/app-only-and-offline.md) and an offline path |

```ts
type GammaErrorCode =
  | 'insufficient_coins' | 'invalid_amount' | 'invalid_reason'
  | 'invalid_data' | 'data_too_large' | 'serialization_error'
  | 'save_failed' | 'rate_limited' | 'forbidden'
  | 'user_not_found' | 'network_error' | 'internal_error'
  | 'dispatch_error' | 'empty_response'
  | 'timeout' | 'unknown_type' | 'no_transport';
```
