Skip to content

Error catalogue

Every application/problem+json error has a type that says which kind of failure it is. This page lists the kinds: the status each one arrives with, when it happens and what to do about it. The error format itself is on Errors, paging and retries.

How to read type

Where your deployment publishes this guide, type is the address of the kind's entry on this page:

{
  "type": "https://docs.example.nl/en/reference/errors/#not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "The prompt was not found.",
  "request_id": "req_5Tn8..."
}
  • Compare type as a whole string when you know your deployment's guide address, and otherwise compare the part after #. That part is the kind, and it is the same in every deployment; the part before it is the guide address of the deployment that answered.
  • A kind never changes: not with a new version, not with the language of your request, not when the wording of title or detail changes. Decide on type and status, and on reason_code where an entry below names one, and show detail to people. A reason_code may gain a new value: treat one you do not know as a plain problem of its status.
  • The address always names this English page. The Dutch page has the same entries under the same anchors: replace /en/ with /nl/ in the address.
  • A deployment that publishes no guide answers "type": "about:blank" on every error. about:blank names no kind: fall back to status.
  • An answer the gateway in front of Core writes itself carries its kind in the same way, where the deployment publishes its guide, and about:blank where it does not. That goes for request-timeout, request-header-fields-too-large, bad-gateway and gateway-timeout, which only the gateway answers, and for any other kind when the gateway answers it. Such an answer has no X-Request-Id header.
  • The five model-call routes answer errors in the vendor's own shape, except the answers listed there. In that shape type is the vendor's word (invalid_request_error) and none of the kinds below. The exceptions are problem+json as everywhere else, with a type as on every other route.

The kinds

Status Kind
400 bad-request
401 unauthenticated
403 forbidden, policy-denied
404 not-found
405 method-not-allowed
408 request-timeout
409 conflict, still-referenced
412 precondition-failed
413 content-too-large
415 unsupported-media-type
416 range-not-satisfiable
422 unprocessable-content, contradicts-stored
429 too-many-requests, usage-cap-reached
431 request-header-fields-too-large
500 internal-error
502 bad-gateway
503 service-unavailable
504 gateway-timeout

bad-request

  • Status: 400
  • When: The request cannot be acted on as it was sent: the HTTP request itself is malformed, or a person's own login returned with a state that is no longer valid.
  • What to do: Correct the request. For a login that failed, have the person start it again from the beginning.

unauthenticated

  • Status: 401, with WWW-Authenticate: Bearer
  • When: The key or token is missing, wrong, expired or revoked.
  • What to do: Check the secret of the API key, or sign in again for a new token. Retrying with the same credential gives the same answer.

forbidden

  • Status: 403
  • When: You are identified, but may not do this, and the reason is not a policy (policy-denied): the operation is not open to your role, for instance, or the organisation or one above it is suspended. A suspension carries "reason_code": "organisation_suspended" and the detail The organisation this key belongs to is suspended. Ask its administrator.; on the Responses routes the same word is error.code. A subject token is also refused this way on a route it may not reach, and on a request that names a person other than its own: A subject token may not reach this route.
  • What to do: Read detail. Use a credential that may do this. On organisation_suspended your key is fine: ask whoever manages the organisation to have it reactivated, and do not retry until then.

policy-denied

  • Status: 403
  • When: The policy of your key, or of the organisation it belongs to, forbids this action: a model, a tool, a host or a resource the policy does not allow. It is also the answer when you may see a thing but a rule's actions do not let the person use, change or delete it, and when a create, rename or relabel would give a thing a name or labels no write rule permits. Nothing is written.
  • What to do: Read detail, which names what was refused. Change the request, or have an administrator change the policy.

not-found

  • Status: 404
  • When: The resource does not exist, belongs to another organisation, or is out of reach of your key: its capability is off or its policy does not name the resource. The answer is the same in all three cases.
  • What to do: Check GET /key for what your key can reach, then the id and the path.

method-not-allowed

  • Status: 405
  • When: The path exists, but not with this HTTP method.
  • What to do: Look the operation up in the API reference.

request-timeout

  • Status: 408, answered by the gateway
  • When: The request, body included, did not arrive in full within 300 seconds (time limit).
  • What to do: Send a smaller body, or send it over a faster connection.

conflict

  • Status: 409
  • When: The current state refuses the request: a name that is already taken, a step that does not follow from the state the resource is in, an organisation that is still being set up or deleted, a datastore record whose unique field holds a value another record already holds (detail names the field), or a write whose If-Match names a version that is no longer the stored one. That last one carries "reason_code": "stale_version" in the body; the other causes carry no reason_code.
  • What to do: Read detail. Read the resource again and decide from its current state; for an organisation that is not ready, try again later. On stale_version, read again and repeat your change on what is stored now (keys).

still-referenced

  • Status: 409, with a conflicts list
  • When: You delete something that is still in use, such as a tool an agent names.
  • What to do: Remove each use listed in conflicts, then delete again. Each entry carries a reason_code from a fixed list your client can switch on (deleting something that is still in use).

precondition-failed

  • Status: 412
  • When: A write named the state it expects in a header, and what is stored is not in that state now: If-Match carries an ETag the record no longer has, because someone wrote or deleted it since you read it, or If-None-Match: * asks to create a record that already exists. Nothing was written.
  • What to do: Read the record again, decide from what it holds now, and send the write with the new ETag (datastores). For a create-only write whose key is taken, read the record under that key and replace it with its ETag, or choose another key.

content-too-large

  • Status: 413
  • When: The request body or the upload is larger than the route accepts. The gateway answers this for most routes; Core answers it for model calls and uploads, and names the limit where it can.
  • What to do: Send less. The same request is refused again.

unsupported-media-type

  • Status: 415
  • When: The body is not a kind of file this route accepts. Core decides from the bytes themselves, not from the Content-Type header.
  • What to do: Send one of the types detail names.

range-not-satisfiable

  • Status: 416, with Content-Range: bytes */<size>
  • When: A download asked for a Range that starts past the end of the file.
  • What to do: Read the size from Content-Range and ask for a range inside it.

unprocessable-content

  • Status: 422, usually with an errors list
  • When: The request was understood, and one or more values in it are refused: a missing field, a wrong type, or a value Core does not accept.
  • What to do: Correct each field in errors (error format). Without a list, read detail. A write a datastore's write function refused carries its reason in refusal. One the function decided nothing about carries error_code: trapped, fuel_exhausted, memory_exceeded, timeout, invalid_arguments, invalid_response, or executor_failed when the function could not run at all (deleted, no such published version, its latest version now reads or writes, or no room to run it right then). A tool that runs on a computer, named where your deployment has none for your organisation, carries "reason_code": "computer_not_configured" at the top level of the problem body, with the detail This tool is not configured on this deployment.; on the Responses routes the same word is error.code. Nothing you change in the request fixes it.

contradicts-stored

  • Status: 422, with a conflicts list
  • When: The request is well formed, but something already stored contradicts it: for example a narrower vocabulary while keys still use a label it would drop.
  • What to do: Change what you send, or change each row in conflicts first. Every contradiction is listed at once, up to the first hundred. Each row carries a reason_code; the one value a 422 uses today is outside_vocabulary.

too-many-requests

  • Status: 429, sometimes with Retry-After
  • When: You send requests faster than the deployment allows; your organisation, or one person in it, already holds as many event streams open as it may; or your organisation already has as many workflow runs open, or as many workflow triggers, as the deployment allows.
  • What to do: Wait as long as Retry-After says when it is present, and otherwise retry with increasing delays. Close a stream you no longer read, let a run end, or remove a trigger.

usage-cap-reached

  • Status: 429, with Retry-After
  • When: The monthly cap of your organisation or of your key is reached. detail says which.
  • What to do: Retry-After holds the seconds until the cap resets; retrying sooner gives the same answer. Have the cap raised if the work cannot wait (your monthly cap).

request-header-fields-too-large

  • Status: 431, answered by the gateway
  • When: The headers of the request are together larger than the gateway accepts.
  • What to do: Send fewer or shorter headers.

internal-error

  • Status: 500
  • When: Something failed that Core did not anticipate. The body never says what.
  • What to do: Keep the request_id and report the failure if it keeps happening. Check what is safe to retry first.

bad-gateway

  • Status: 502, answered by the gateway
  • When: The gateway got no usable answer from Core, for instance during a restart.
  • What to do: Retry with increasing delays, within what is safe to retry.

service-unavailable

  • Status: 503, sometimes with Retry-After
  • When: Something Core needs is out of reach for the moment, another request is changing the same thing, or the gateway is shedding load.
  • What to do: Wait as long as Retry-After says when it is there, and otherwise retry with increasing delays.

gateway-timeout

  • Status: 504, answered by the gateway
  • When: Core did not answer within the time the route allows.
  • What to do: The request may still have been carried out. Read the resource before you send again, or retry with an idempotency key.