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

# Errors

> Hoe de merchant MCP fouten meldt: HTTP-afwijzingen, isError-toolresultaten en stabiele errorcodes, plus retryregels voor writes die time-outen.

Fouten komen op twee niveaus naar boven. Problemen met authenticatie, origin en rate limits worden **vóór** MCP afgewezen, als gewone HTTP-responses. Alles wat binnen een toolcall gebeurt, komt terug als een MCP-toolresultaat met `isError: true`.

## Op HTTP-niveau

| Status | Oorzaak | Body |
| - | - | - |
| `401` | Ontbrekende of ongeldige credential | `WWW-Authenticate: Bearer realm="OAuth", resource_metadata="…"`-header; start OAuth-discovery |
| `403` | `Origin`-header niet op de allow-list | `{ "error": "Origin not allowed" }` |
| `429` | Meer dan 60 verzoeken in een minuut voor deze gebruiker of sleutel | `{ "error": "Rate limit exceeded" }` met `Retry-After` in seconden |

Deze vallen buiten de MCP-envelop; een MCP-clientbibliotheek verheft ze doorgaans tot transportfouten.

## Tool-errors

Een mislukte toolcall is een normale JSON-RPC-success waarvan het resultaat `isError: true`, één tekstblok en **geen** `structuredContent` heeft:

```json theme={null}
{
  "isError": true,
  "content": [
    {
      "type": "text",
      "text": "{\"error\":{\"code\":\"INVALID_INPUT\",\"message\":\"Date range exceeds 90 days\",\"nextSteps\":[\"Split the range into shorter intervals.\"],\"retryable\":false}}"
    }
  ]
}
```

Parse de tekst als JSON om te krijgen:

| Veld | Betekenis |
| - | - |
| `code` | Een van de onderstaande codes. Stabiel; vertakking op basis hiervan |
| `message` | Korte, veilige beschrijving. Voor `INVALID_INPUT` benoemt hij het probleem; voor andere codes is het een vaste zin |
| `nextSteps` | Instructies die een agent kan opvolgen |
| `retryable` | Momenteel altijd `false` — zie [Retries](#retries) |

Er wordt niets anders van de onderliggende fout blootgelegd: geen stacktraces, SQL, upstream-responses of interne IDs. Elk verzoek wordt server-side gelogd met de `x-request-id` die op de HTTP-response wordt geëchood; noem die als je contact opneemt met support.

## Codes

| Code | Wanneer | Typische fix |
| - | - | - |
| `INVALID_INPUT` | Schemaovertreding, een datumbereik van meer dan 90 dagen, een write-timestamp zonder offset, `period` gecombineerd met `from`/`to`, een account-brede statsquery op een multi-valuta-account | Corrigeer de argumenten; `message` zegt wat er misging |
| `PERMISSION_DENIED` | De credential mag niet op dit account handelen | Controleer de sleutel of token |
| `NOT_FOUND` | Het filiaal, de bestelling, het menu of de link bestaat niet **op dit account** — resources op andere accounts zien er identiek uit aan niet-bestaande | Roep `list-venues` (of de relevante list-tool) aan en controleer het ID |
| `CONFLICT` | Status voorkomt de write, bijv. een kortingscode die op dat filiaal al is gebruikt | Lees de huidige status en beslis dan |
| `TIMEOUT` | De tool overschreed 30 seconden, of een upstream-call timeoutte | Vernauw de query. Voor een write, **controleer de status voordat je opnieuw probeert** |
| `UPSTREAM_UNAVAILABLE` | Een afhankelijkheid (database, payments provider) kon niet worden bereikt | Wacht, probeer reads dan opnieuw; controleer de status voordat je writes opnieuw probeert |
| `INTERNAL_ERROR` | Iets onverwachts | Probeer reads eenmaal opnieuw; mail [mcp@storekit.com](mailto:mcp@storekit.com) met het request ID als het aanhoudt |

## Retries

Reads (`readOnlyHint: true`) zijn veilig om opnieuw te proberen na `TIMEOUT`, `UPSTREAM_UNAVAILABLE` of `INTERNAL_ERROR`, met backoff.

Writes liggen anders. `create-discount-code` en `create-payment-link` zijn gemarkeerd als `idempotentHint: false` en hebben geen idempotency key. Een `TIMEOUT` wordt teruggegeven als de 30-secondenbegroting op is, wat kan gebeuren **nadat** de rij is gecommit — de code of link bestaat mogelijk al. Voordat je een write opnieuw probeert:

1. `list-discount-codes` en zoek naar de code, of `list-payment-links` gefilterd op filiaal en zoek naar de titel/referentie.
2. Roep de write alleen opnieuw aan als hij afwezig is.

Herhaal writes nooit automatisch. Daarom is `retryable` vandaag op elke code `false`: de server weet niet of jouw write is doorgekomen, dus zegt hij je niet om opnieuw te proberen.

## Validatiefouten van je client

Omdat errors geen `structuredContent` dragen, slaan spec-compliant clients (waaronder de officiële TypeScript SDK) output-schema-validatie op hen over en tonen ze de envelop. Als je client in plaats daarvan een `-32602` of "structured content does not match schema"-fout meldt, valideert hij de *tekst* tegen de `outputSchema` van de tool; lees het tekstblok direct.


## Related topics

- [Response-formaat](/docs/nl/developers/mcp/response-format.md)
- [Troubleshooting](/docs/nl/guides/integrations/pos/comtrex/troubleshooting.md)
- [Logboek geblokkeerde bestellingen: afgewezen checkouts](/docs/nl/guides/orders/advanced/blocked-orders.md)
- [Merchant MCP-overzicht](/docs/nl/developers/mcp/overview.md)
- [Zonal (Aztec)](/docs/nl/guides/integrations/pos/zonal.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.