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

# Errors

> Stable error codes, and what a client should do next.

A failed tool call is a normal `tools/call` result with `isError: true`. The body is JSON in `content[0].text`:

```json theme={null}
{
  "error": "scan_required",
  "next_action": "start_scan",
  "instructions": "This needs a completed scan. Call start_skin_scan first, …"
}
```

| Field                 | Present               | Meaning                                                                                                |
| --------------------- | --------------------- | ------------------------------------------------------------------------------------------------------ |
| `error`               | Always                | Stable code from the table below                                                                       |
| `next_action`         | Always                | One of `start_scan`, `wait_for_upload`, `check_again`, `retry_later`, `fix_request`, `sign_in`, `stop` |
| `instructions`        | Always                | Guidance written for the model to act on and relay                                                     |
| `retry_after_seconds` | Rate limits and waits | Seconds to wait before retrying                                                                        |
| `detail`              | `invalid_input` only  | Which arguments were wrong, at most 300 characters                                                     |

Bodies never contain stack traces, upstream URLs, tokens or internal identifiers. A scan that doesn't exist and a scan that isn't yours both return `not_found`.

<Note>
  **An exhausted free allowance is not an error.** The tool succeeds with an empty list and `entitlement.upgrade_required: true`. Check that field before telling the person nothing matched. See [limits](/limits).
</Note>

## Codes

| Code                       | `next_action`     | Instructions returned to the model                                                                                                                                                                                                                                                                                                                              |
| -------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `account_required`         | `sign_in`         | This needs the person's Skan account, connected with Google or Apple. An anonymous or guest identity cannot be used. Explain what connecting gets them and let them decline.                                                                                                                                                                                    |
| `admissions_paused`        | `stop`            | New scans are switched off right now. Say so plainly and do not retry. Other things, like ingredient questions, may still work.                                                                                                                                                                                                                                 |
| `already_submitted`        | `check_again`     | A photo has already been given for this scan. Call get\_skin\_scan for its progress instead of sending another.                                                                                                                                                                                                                                                 |
| `body_timeout`             | `retry_later`     | The request body did not arrive in time. Retry once; if it fails again the payload is probably too large to send inline, so use the upload link instead.                                                                                                                                                                                                        |
| `busy`                     | `retry_later`     | Too much work is already in flight for this scan. Wait retry\_after\_seconds and check again rather than starting another scan.                                                                                                                                                                                                                                 |
| `capacity_paused`          | `retry_later`     | Skan is at capacity, not broken. Tell the person to try again later and stop calling for now.                                                                                                                                                                                                                                                                   |
| `catalog_unavailable`      | `retry_later`     | The product and ingredient data is temporarily unreachable. Wait retry\_after\_seconds or answer without it. Never invent a product, a price or an ingredient effect.                                                                                                                                                                                           |
| `challenge_failed`         | `wait_for_upload` | Skan's anti-abuse check did not pass in the person's browser. Give them the upload\_url again and let them retry there. You cannot pass this check on their behalf.                                                                                                                                                                                             |
| `claiming_disabled`        | `stop`            | Saving a scan to a Skan account is switched off for this connector. The scan and its scores still work; tell the person saving is unavailable.                                                                                                                                                                                                                  |
| `consent_page_required`    | `wait_for_upload` | This connector does not accept a photo sent through the conversation. Call start\_skin\_scan without a photo and give the person the upload\_url it returns.                                                                                                                                                                                                    |
| `consent_required`         | `wait_for_upload` | Only the person's own browser, the one that agreed to the scan, can do this. Give them the link and let them act there. You cannot consent on their behalf.                                                                                                                                                                                                     |
| `empty_body`               | `fix_request`     | The request had no body. Send the tool call arguments.                                                                                                                                                                                                                                                                                                          |
| `feature_unavailable`      | `stop`            | This capability is switched off for this connector. Do not retry. The scan tools may still work.                                                                                                                                                                                                                                                                |
| `image_quality`            | `start_scan`      | The photo could not be read clearly. Ask for a new one: front-facing, even lighting, no filters. This is a photo problem, not a fault the person should be apologised to for at length.                                                                                                                                                                         |
| `invalid_image`            | `fix_request`     | That was not a readable JPEG or PNG. Do not retype, re-encode or generate the image yourself. If the person attached an ordinary photo, your host probably did not pass you its file: call start\_skin\_scan again without `photo` and give them the upload\_url instead, where they choose the same photo themselves.                                          |
| `invalid_image_dimensions` | `fix_request`     | The photo has too many pixels to accept inline — a full-resolution camera photo usually does. Do not ask the person for a different photo and do not try to resize it yourself: call start\_skin\_scan again without `photo` and give them the upload\_url it returns, where their own browser resizes it before it is sent. The same photo will work that way. |
| `invalid_input`            | `fix_request`     | The arguments did not match the tool's schema. Read the schema and correct them. Do not retry the same arguments.                                                                                                                                                                                                                                               |
| `invalid_json`             | `fix_request`     | The request body was not valid JSON. Send a well-formed tool call; do not retry the same bytes.                                                                                                                                                                                                                                                                 |
| `invalid_origin`           | `stop`            | This request was refused because of where it came from. Do not retry; this is a deployment problem, not something the person did.                                                                                                                                                                                                                               |
| `invalid_request`          | `fix_request`     | The request was malformed. Correct it against the tool schema rather than retrying it unchanged.                                                                                                                                                                                                                                                                |
| `invalid_scope`            | `sign_in`         | The access token does not carry the scope this tool needs. Request the scope during authorization and try again.                                                                                                                                                                                                                                                |
| `invalid_token`            | `sign_in`         | The access token is missing, expired or not valid for this resource. Refresh it, or send the person through sign-in again. Do not retry with the same token.                                                                                                                                                                                                    |
| `network_identity_missing` | `stop`            | Skan could not identify the calling network, so it refused the request. Do not retry.                                                                                                                                                                                                                                                                           |
| `not_configured`           | `retry_later`     | This part of Skan is not configured right now. Do not retry in a loop; tell the person it is unavailable.                                                                                                                                                                                                                                                       |
| `not_entitled`             | `stop`            | This connector is not approved for that capability. Do not retry.                                                                                                                                                                                                                                                                                               |
| `not_found`                | `stop`            | That scan does not exist, has expired, or does not belong to this conversation. Do not retry and do not guess another run\_id. Offer to start a new scan only if the person asks.                                                                                                                                                                               |
| `payload_too_large`        | `fix_request`     | The photo is too large. Ask the person for a smaller one, or call start\_skin\_scan without a photo and give them the upload\_url so their browser can resize it.                                                                                                                                                                                               |
| `provider_error`           | `retry_later`     | The skin-analysis provider failed. Do not repeat the call immediately and do not invent scores. If it persists, tell the person the analysis is unavailable.                                                                                                                                                                                                    |
| `rate_limited`             | `retry_later`     | Too many requests. Wait retry\_after\_seconds before trying again. Do not retry immediately and do not work around it by starting another scan.                                                                                                                                                                                                                 |
| `request_failed`           | `retry_later`     | Something went wrong at Skan's end. Do not repeat the call immediately. If it persists, tell the person rather than retrying in a loop.                                                                                                                                                                                                                         |
| `result_unavailable`       | `stop`            | The result for that scan is no longer stored. Do not retry. Offer a new scan only if the person asks.                                                                                                                                                                                                                                                           |
| `scan_limit_reached`       | `retry_later`     | The free scan allowance for this person or this period is used up. Tell them, and point them at the Skan app. Do not retry or start another scan to get around it.                                                                                                                                                                                              |
| `scan_not_ready`           | `check_again`     | The scan is still being analysed. Wait retry\_after\_seconds, call get\_skin\_scan, and only call this again once that reports completed. Do not start another scan.                                                                                                                                                                                            |
| `scan_not_uploaded`        | `wait_for_upload` | The scan exists but the person has not given their photo yet. If you have an upload\_url, give it to them; otherwise ask them for a photo. Do not retry this call until the scan reports completed.                                                                                                                                                             |
| `scan_required`            | `start_scan`      | This needs a completed scan. Call start\_skin\_scan first, wait for it to finish, then call this again with that scan's run\_id and access\_token. Tell the person a scan is needed rather than apologising for an error.                                                                                                                                       |
| `service_paused`           | `retry_later`     | Skan is at capacity, not broken. Tell the person to try again later and stop calling for now.                                                                                                                                                                                                                                                                   |
| `session_limit_reached`    | `retry_later`     | Skan is not accepting new scans at this moment. Wait and try again later.                                                                                                                                                                                                                                                                                       |
| `unauthorized`             | `sign_in`         | This endpoint needs the person's Skan account. Send them through the connector's sign-in flow and retry with the access token it issues.                                                                                                                                                                                                                        |
| `unsupported_image_type`   | `fix_request`     | Only JPEG and PNG are accepted, and media\_type must match the bytes actually sent.                                                                                                                                                                                                                                                                             |
| `upload_in_progress`       | `check_again`     | The person's photo is already being uploaded. Wait retry\_after\_seconds and call get\_skin\_scan; do not send a photo again.                                                                                                                                                                                                                                   |
