<!-- AI agents: this is the Markdown version of an AppNorth documentation page. Index: https://www.appnorth.app/llms.txt -->

# Errors

The Swift SDK throws `AppNorthError`. Server responses use stable error codes for program logic; show a helpful explanation to the user instead of displaying the code alone.

## Swift error cases {#swift}

| Case                                | Meaning and recovery                                                                           |
| ----------------------------------- | ---------------------------------------------------------------------------------------------- |
| `invalidConfiguration(String)`      | Fix the API URL, public App ID or origin before constructing the client                        |
| `invalidIdentityCredential(String)` | Obtain a valid credential from your authenticated backend                                      |
| `invalidResponse`                   | The transport did not return an HTTP response; inspect your transport integration              |
| `network(String)`                   | Connectivity failed; retry with a bounded delay                                                |
| `server(status:code:fields:)`       | Inspect the HTTP status, stable code and optional field errors                                 |
| `decoding(String)`                  | The success response could not be decoded; check SDK/server compatibility and the API base URL |

`AppNorthOfflineQueueError` separately reports persisted-queue failures. See [Offline and cache](/docs/offline-and-cache) for storage and replay behavior.

## Public API failures {#server}

| Code or response                         | Action                                                                                                                     |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_APP_ID`, `PROJECT_NOT_FOUND`    | Copy the public App ID from the correct app's installation page                                                            |
| `APP_ID_MISMATCH`                        | Use the same public App ID in the feedback body and query                                                                  |
| `INVALID_JSON`, `UNSUPPORTED_MEDIA_TYPE` | Send valid JSON with `Content-Type: application/json`                                                                      |
| `INVALID_IDEMPOTENCY_KEY`                | Supply a key in the format documented in Limits                                                                            |
| `IDEMPOTENCY_CONFLICT`                   | The key was already used for a different payload; preserve the original key for retries and use a new one for a new intent |
| `INVALID_SCREENSHOT`                     | Validate the image data URL and screenshot limits                                                                          |
| `INVALID_PAYLOAD`, `INVALID_QUERY`       | Correct the fields or query parameters; do not blindly retry                                                               |
| `ORIGIN_NOT_ALLOWED`                     | Correct the configured origin and app's allowed domain                                                                     |
| `IDENTITY_REQUIRED`                      | Supply a credential for an identified-only operation                                                                       |
| `INVALID_IDENTITY`                       | Renew the signed credential; check expiry and signing inputs on your backend                                               |
| `IDENTITY_NOT_CONFIGURED`                | Configure identity verification for this app on the server                                                                 |
| `IDENTITY_EMAIL_MISMATCH`                | Match the feedback email to the verified identity                                                                          |
| `CHAT_DISABLED`                          | Enable the intended chat mode in the app's settings                                                                        |
| `FEEDBACK_NOT_FOUND`                     | Treat the private thread as unavailable to this identity                                                                   |
| `RATE_LIMITED` / HTTP 429                | Wait for `Retry-After` when provided and reduce parallel requests                                                          |
| HTTP 413                                 | Reduce the request body, screenshot or diagnostics                                                                         |
| HTTP 5xx                                 | Retry recoverable failures with bounded backoff; investigate persistent failures                                           |

Keep the same idempotency key when retrying the same mutation. Do not change its payload and reuse that key. Private resources can return 404 without disclosing another user's data.

## Dashboard and provider errors {#integrations}

`UNAUTHORIZED` requires a dashboard session; `FORBIDDEN` requires the appropriate workspace role. `FORBIDDEN_ORIGIN` rejects a cross-origin mutation. `PLAN_REQUIRED` indicates unavailable feature access or allowance.

For `CREDENTIALS_REJECTED`, review provider credentials. For `CREDENTIALS_UNREADABLE` or `ENCRYPTION_NOT_CONFIGURED`, the deployment operator must check credential encryption. Never solve these by putting secrets in the client.

See [Metadata](/docs/metadata#conflicts) for stale and partial publication, [Price localization](/docs/price-localization#results) for uncertain writes, and [Troubleshooting](/docs/troubleshooting) for symptom-based checks.

## Report a failure {#support}

Record the route, HTTP status, error code, SDK version and correlation ID when available. Public responses can include `correlationId`; the current Swift `server` case exposes status, code and fields, not a correlation-ID property. Capture safe response metadata through your transport if you need that identifier.

Do not log identity signatures, API keys, private report bodies or screenshots.
