Reference
Error codes
Every stable error code Hatched raises — HTTP status, SDK class, and how to fix.
Every error response follows the canonical envelope:
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 60s",
"requestId": "req_abc_123",
"details": { "...": "..." }
}
}The SDK parses this envelope and throws a typed subclass of HatchedError with code, statusCode, requestId, and details.
Catalogue
| Code | HTTP | SDK class | Meaning |
|---|---|---|---|
unauthorized | 401 | UnauthorizedError | The API key is missing, invalid, or revoked. |
forbidden | 403 | ForbiddenError | Key is valid but lacks permission for this endpoint. |
publishable_key_scope | 403 | PublishableKeyScopeError | Publishable key cannot mutate — use a secret key server-side. |
resource_not_found | 404 | NotFoundError | The referenced id does not exist or was archived. |
config_version_mismatch | 409 | ConfigVersionMismatchError | The buddy is pinned to a different config version than expected. |
conflict | 409 | ConflictError | A competing mutation won; retry is safe if you re-read state first. |
validation_failed | 422 | ValidationError | Fields failed schema/business validation. See err.details.fields. |
insufficient_balance | 400 | InsufficientBalanceError | Buddy does not have enough coins/tokens for the spend. |
rate_limited | 429 | RateLimitError | Over the per-minute quota. Honour err.retryAfter (seconds). |
upstream_image_error | 502 | UpstreamImageError | The art provider failed during hatch/evolve. No ledger writes happened. |
unauthorized
- HTTP status: 401
- SDK class:
UnauthorizedError(from@hatched/sdk-js) - Meaning: The API key is missing, invalid, or revoked.
- Fix: Double-check
HATCHED_API_KEY; rotate in Dashboard → Developers if leaked. - More: Troubleshooting →
forbidden
- HTTP status: 403
- SDK class:
ForbiddenError(from@hatched/sdk-js) - Meaning: Key is valid but lacks permission for this endpoint.
- Fix: Check your plan tier or the key's scope.
publishable_key_scope
- HTTP status: 403
- SDK class:
PublishableKeyScopeError(from@hatched/sdk-js) - Meaning: Publishable key cannot mutate — use a secret key server-side.
- Fix: Move the call to a server route. See Auth model.
- More: Troubleshooting →
resource_not_found
- HTTP status: 404
- SDK class:
NotFoundError(from@hatched/sdk-js) - Meaning: The referenced id does not exist or was archived.
- Fix: Verify the id from a recent list/create response.
config_version_mismatch
- HTTP status: 409
- SDK class:
ConfigVersionMismatchError(from@hatched/sdk-js) - Meaning: The buddy is pinned to a different config version than expected.
- Fix: Migrate the buddy or pin your write to its current config.
conflict
- HTTP status: 409
- SDK class:
ConflictError(from@hatched/sdk-js) - Meaning: A competing mutation won; retry is safe if you re-read state first.
- Fix: Re-fetch the resource and retry the mutation.
validation_failed
- HTTP status: 422
- SDK class:
ValidationError(from@hatched/sdk-js) - Meaning: Fields failed schema/business validation. See
err.details.fields. - Fix: Log
err.details; fix the failing field and resend. - More: Troubleshooting →
insufficient_balance
- HTTP status: 400
- SDK class:
InsufficientBalanceError(from@hatched/sdk-js) - Meaning: Buddy does not have enough coins/tokens for the spend.
- Fix: Check
err.balance/err.required; surface to the user.
rate_limited
- HTTP status: 429
- SDK class:
RateLimitError(from@hatched/sdk-js) - Meaning: Over the per-minute quota. Honour
err.retryAfter(seconds). - Fix: Let the SDK retry (default on) or backoff manually.
- More: Troubleshooting →
upstream_image_error
- HTTP status: 502
- SDK class:
UpstreamImageError(from@hatched/sdk-js) - Meaning: The art provider failed during hatch/evolve. No ledger writes happened.
- Fix: Re-call the operation; idempotent.
- More: Troubleshooting →
Programmatic handling
import {
HatchedError,
ValidationError,
RateLimitError,
InsufficientBalanceError,
} from '@hatched/sdk-js';
try {
await hatched.buddies.spend(buddyId, { amount: 100, reason: "item" });
} catch (err) {
if (err instanceof InsufficientBalanceError) {
return showInsufficientFunds(err.balance, err.required);
}
if (err instanceof ValidationError) {
return showFieldErrors(err.details);
}
if (err instanceof RateLimitError) {
return retryLater(err.retryAfter);
}
if (err instanceof HatchedError) {
console.error(err.code, err.requestId, err.message);
}
throw err;
}