# Errors Interfold uses HTTP status codes and a consistent JSON error envelope. ## Error envelope ```json { "error": { "code": "not_found", "message": "Site not found" } } ``` Every REST API error body is rooted at `error`. Use the stable, generic snake-case `error.code` for branching and `error.message` for people or logs. Do not expect an HTTP status field, a top-level `message`, or top-level recovery fields. Some operations include useful validation or recovery metadata in `error.details`. It is omitted when there is no meaningful structured metadata. For example, a migration conflict can include its operation-specific code and a safe retry instruction without changing the generic `conflict` code: ```json { "error": { "code": "conflict", "message": "Another migration apply is active", "details": { "code": "MIGRATION_LOCKED", "retryable": true, "nextAction": "RETRY_MIGRATIONS_APPLY", "nextCommand": "interfold db migrations apply --site site_123 --confirm" } } } ``` Treat `details` as operation-specific metadata. Preserve it when relaying a failure, but branch on it only where the operation documents that behavior. ## Status codes | Status | `error.code` | Meaning | | ------ | ------------------------- | ---------------------------------------------------------- | | `400` | `bad_request` | Validation failed or the request is malformed. | | `401` | `unauthorized` | Authentication is missing or invalid. | | `403` | `forbidden` | The caller or key permission cannot perform the operation. | | `404` | `not_found` | The resource does not exist or is not visible to the caller. | | `405` | `method_not_allowed` | The HTTP method is not supported. | | `409` | `conflict` | The requested change conflicts with current state. | | `413` | `payload_too_large` | The request body is too large. | | `422` | `unprocessable_entity` | The request is valid but cannot be completed. | | `429` | `too_many_requests` | The account exceeded its request budget. | | `500` | `internal_server_error` | An unexpected Interfold failure occurred. | | `502` | `bad_gateway` | An upstream provider failed. | | `503` | `service_unavailable` | A required service is unavailable. | | `504` | `gateway_timeout` | An upstream request timed out. | ## Retry safely Do not retry every failure automatically. - Fix `400`, `401`, `403`, and `422` responses before retrying. - Re-read the resource after ambiguous write failures. - Respect `Retry-After` on `429` responses. - Use structured migration `error.details.nextAction` and `error.details.nextCommand` when present. - Do not retry an external side effect when the first result is unknown unless the operation documents idempotency. ## Request IDs When a response includes a request or operation identifier, record it with the status, error code, and timestamp. Include those details when reporting a problem. ## Transport exceptions The raw object `GET` and `HEAD` endpoints can stream file content. Failures detected before streaming begins use this JSON envelope. If streaming has already started, HTTP cannot replace the body with JSON; Interfold safely ends that stream instead. Hosted function and cron responses are application responses supplied by the Site, rather than REST API error bodies. MCP also has its own protocol-level tool-error result; its client preserves the REST `code`, `message`, and `details` when an underlying REST call fails.