Format run model 400 invalid_request: unknown id or closed catalog
A model Sume cannot admit on a Format run is a 400, not a silent swap. The order ids are checked in, and why a real Claude id can still fail in your workspace.

A Format run whose model Sume cannot admit fails with 400 invalid_request before anything is spent. Two different causes produce it: the id is not in the Agents catalog at all, or it is a real catalog id whose gate is closed in your environment. In neither case does Sume swap in another model.
In what order does Sume check a model id?
The registry's resolver, which the Format create path uses, works in a fixed order. The docs describe the outcome, an id outside the catalog is 400 invalid_request, and the code gives the steps:
- The comment on the resolver says the same in words: a silent downgrade is how a user ends up billed for something they did not choose, so unknown ids and closed gates fail closed.
- Step 3 is the only place a string can mean something other than what it says: a Cursor-era id is accepted and runs GPT-6 Sol.
| Step | Input | Result |
|---|---|---|
| 1 | Omitted or empty | The default for the surface; on a Format run that is gpt-6.1-sol |
| 2 | Not a string | Refused |
| 3 | An old Cursor-era id such as grok-4.5 | Resolved to gpt-6-sol |
| 4 | Any spelling of a catalog row | Normalized to the row's id and moved through its unconditional retirement |
| 5 | Row retired with a gated successor | The successor, where that id is admitted |
| 6 | Admission by the row's gate | Admitted, or refused as 400 |
| 7 | No row at all | Refused as 400 |
Why would a valid Claude or Grok id fail?
Because "in the catalog" and "listed in your workspace" are different. Sume gates rows by environment. Opus 5.5, GPT-6 Sol and GPT-6.1 Sol are listed on every catalog, while Sonnet 5.5, Haiku 4.5, GPT-6 Luna and the DeepSeek rows depend on an OpenRouter catalog flag, and Grok 4.7 depends on a Grok flag. A request for a gated row where the flag is closed is a 400, not a move onto a GPT.
So the same payload can pass in one environment and fail in another. The check is cheap: open the Agents model picker in the workspace that owns your key and see whether the id is listed, before you ship it.
How do I handle the error in code?
Treat the 400 as a configuration error, not a retryable one. The errors page lists invalid_request with the other causes, such as a body naming none of instruction, input, previous_run_id or attachments, so branch on the message and not just the code.
Do not auto-retry with a different model string. If you want a fallback, make it an explicit second request that you log, so a cost report never shows a model you did not decide on.
What does a failed create call cost?
Nothing. The model is resolved before the runner is provisioned and before anything is spent, which is why the 400 comes back immediately and why your balance and generation_spend_cap_usd are untouched. A bad model string is therefore a cheap mistake, as long as you read the response instead of retrying it in a loop.
Pair this with an Idempotency-Key on every create, as the docs require. A corrected request is a new body, so it needs a new key, or you will hit a conflict instead of a run.
What about retired ids that moved?
Those do not fail. gpt-5.6-sol runs on gpt-6-sol, Sonnet 5 runs on Sonnet 5.5 and Opus 5 on Opus 5.5, all by design. Unconditional means unconditional: they succeed in an environment where the original was never listed, as long as the successor is admitted. Read model on the receipt, documented in Runs and results, to see where each landed, and see the Sonnet 5.5 id post for the spellings.
Sources
Related posts
More in Developers
- Format run on_active_run: allow, skip or reject with a 409?
on_active_run sets what a second Format run does while one is in flight: allow runs both, skip records a skipped run, reject answers 409 format_run_in_progress.
- Sume Idempotency-Key design: one key per order and revision
Build Idempotency-Key from your own order id plus a revision number, so retries return the same Sume job and a changed prompt is a deliberate new key.
- Sume image edit returns 400: input_references on a text-only model
A Sume image edit fails with 400 when the model's input_references range is 0 to 0. Read the descriptor, pick a model that accepts references, and retry.
- Image reference URL rejected on Sume: localhost, http, private hosts
Sume's Image API rejects localhost, private-network and non-HTTPS reference URLs before submission. A pre-flight check in Python and what to host instead.
Written by Sume