application/problem+json. There is no second error format anywhere in the product, so one way of reading an error works on every surface, from Cortex Chat to Cortex Code to the Cortex CLI.
This page explains the fields of a problem document, which of them are a contract and which are only prose, how to get from an error to the page that explains it, and what retrying does and does not fix. It then lists every code Cortex emits, with its HTTP status, whether retrying helps, and the message the product shows for it.
The shape of a problem document
How to read one
Read the four always-present fields in this order, and you have everything you need.codetells you what happened. The same code means the same thing on every surface and in every product, which is why it is the only field worth writing logic against.typetells you where it is explained. The problem type base ishttps://docs.cortex.foundation/problems, andtypeis that base plus/{code}. So aquota_exceededfailure carriestype: "https://docs.cortex.foundation/problems/quota_exceeded", and following that URL lands on the page for it. Every code below has one.statustells you the class of the failure, and is the fastest way to sort a pile of errors into “my request was wrong”, “I am not allowed”, “I am going too fast” and “Cortex broke”. It is not precise enough to act on: two different 429s mean two different things.request_idtells you which request this was. One id identifies one failed request.
detail is the part that varies. The other fields are the same for every occurrence of a code, while detail describes this one occurrence, and it is written for a person reading raw output, not for a user interface. It may name a Cortex surface or a specific resource. Treat it as diagnostic text: log it, and do not build anything on its wording.
What is safe to show a user
The web app never renders the wiretitle or detail. It looks the code up in its own message catalogue and shows that instead. Anything you build against these documents should do the same.
- Write your own copy per
code. The page for each code explains the situation in product language. - Do not render
detailas the primary message. It is not the user’s message. - Exactly three codes may show
detailas a secondary line:validation_failed,bad_requestandinvalid_state. Even there it supplements the message rather than being it. internaldeliberately carries nothing. A 500 arrives with a status, the generic title and arequest_id, and never adetail, field errors or extensions. The reference id is the only actionable thing in it, and the product’s own copy says so.
Errors never name a vendor
Before any message reaches a user, an internal service name is converted into product language. What you will see is a Cortex surface, in one of two sentences: “<phrase> is temporarily unavailable.” or “<phrase> did not respond in time.”
The phrases are product-facing and stable enough to recognise: Sign-in, The assistant, The audio service, Connected apps, The plugin service, The payments service, The memory service, The bot computer, The Code runtime, The remote host, Cortex Security, The model catalogue, Image generation, Document export, Literature search, Origin detection, and This feature as a fallback. No subprocessor is ever named in an error.
The reference id
request_id is always present, and it is the one value in a problem document that is designed to be shown to a user. In the product it appears at the bottom of an error card as Reference followed by the id. That string is the same value as request_id in the document behind the card.
1
Read the error card
The line beginning Reference holds the id.
2
Copy it before you retry
A retry produces a new id. The one that matters is the id from the request that failed.
3
Quote it when you get in touch
One id identifies one request, which is what lets support find it. For an
internal failure the copy already asks for this: “This was not your fault and it has been recorded. Quote the id below if you get in touch.”Rejected fields
validation_failed is the only code that carries per-field detail, as an errors array. Each entry has three keys.
The product renders its own sentence per field code: “This is longer than allowed.”, “This is required.”, “This is not one of the accepted values.”, and “This was not accepted.” for anything it does not recognise. Showing the field errors next to the fields they point at is the whole value of this code, so prefer that over a single summary message.
Typed extras, by code
Some codes carry extra members alongside the standard fields. They are typed, so you can rely on them where the code says they appear.Every code Cortex emits
Twenty-four codes, each with its own page. The What the product shows column is the heading a user actually reads in the app, so it is the fastest way to match an error you were sent a screenshot of to the code behind it.
Grouped by status, in the order you are most likely to meet them:
A retired capability answers
gone rather than pretending to work or disappearing into a 404, so gone is worth handling even if you have never seen it.
Retrying
Seven codes are retryable:conflict, rate_limited, internal, upstream_failure, upstream_timeout, service_unavailable and no_capacity. For every other code the same request will fail the same way, and the request, the plan or the state has to change first.
rate_limitedcarriesretry_after_seconds. Wait that long, then back off. The product shows either “You can try again in” a label, or “You can try again now.”conflictis the one retryable 4xx. Something changed underneath you, so reload to pick up the current version and apply your change again.no_capacityis specific to one model. Try again shortly, or pick another model. When the document carries afallback_model, the product offers Continue with that model as a button, which is a choice you make rather than a substitution made for you.internal,upstream_failure,upstream_timeoutandservice_unavailableare ours. Retry, keep the reference id, and check System status if it repeats.
When it was not your fault
Three codes are always Cortex’s own problem:internal, upstream_failure and upstream_timeout. The product says so in as many words, because a user who has just lost a turn deserves to know whether to keep trying. Nothing is expected of you beyond keeping the reference id. A request that reached the assistant and came back an error often succeeds on a retry; one that timed out was abandoned rather than left hanging, and a shorter prompt usually gets through.
When there is no problem document
If the request never reached Cortex, there is nothing to read. The product says You appear to be offline with “Nothing was sent. This works again as soon as the connection is back.”, or The request could not be completed with “Something went wrong before the request finished. Trying again usually works.”A network failure is not a problem document. There is no
code and no request_id to quote for one, so a report of “it just failed” with no reference id is usually this, not a Cortex error.Codes that are not problem codes
Cortex Security records its own reasons when a pull-request review cannot run:upstream_unconfigured, no_model_available, app_not_configured, diff_unavailable, nothing_to_review, installation_suspended and review_incomplete. These are stored with the review and rendered as a sentence on the review itself. They are not HTTP problem codes, they never appear in a problem document, and they have no page in the catalogue. Security troubleshooting covers each of these situations and what to do about it.
Related
Problem catalog
Every code with its status and retry answer, and a page per code.
Limits and quotas
The windows behind
quota_exceeded, and what resets when.Troubleshooting
What a message you see in the product means, by symptom.
System status
Whether something is down right now, which this page cannot tell you.
- Models for the model names behind
no_capacityandfallback_model. - Security and privacy for what is kept in a log alongside a reference id.