The Gateway returned 400 to every OpenAI request for three months
One sampling parameter the caller never asked for, roughly 1,395 consecutive failures, and three months of blaming the provider credentials.
Three months of "the managed provider credentials need checking" was one line.
body.reasoning_effort = "minimal";Sent unconditionally to every model matching /^(gpt-5|o1|o3|o4)/, which is most of the OpenAI catalogue. OpenAI rejects it:
400 Unsupported value: 'reasoning_effort' does not support 'minimal' with
this model. Supported values are: 'none','low','medium','high','xhigh'.It was never the credentials
The ledger carries roughly 1,395 consecutive failures on gpt-5 from June to September with not one success. Every row in the newer request trace is the same 400. The handful of requests that ever worked were on models the regex happened not to match.
A bad key surfaces as a 502 on this path, and every trace row said 400 and validation. The evidence to distinguish the two was sitting in a table nobody read.
It was the second time
The Gateway had already invented a sampling parameter its caller never asked for and had the provider refuse it: temperature on Anthropic. The comment fixing that is still there, four files away, describing this exact failure. It was fixed for one provider and not the other.
The value is a named constant now, and scripts/api-layer-check.ts asserts it is in the set OpenAI's own error message enumerates. Verified by putting "minimal" back: two checks fail, precisely.
Parallel tool calls could not work on any Claude model
Anthropic requires strictly alternating roles; OpenAI's shape does not. A turn with two parallel tool calls is one assistant message and two role: "tool" messages, and a tool result maps onto a user turn here — so the converter emitted two consecutive user turns and Anthropic returned a 400.
It takes a second simultaneous call to appear. One at a time alternates correctly and always has, which is why a chat window never found it and an agent loop finds it on its first real task. Consecutive same-role messages now fold into one entry, which is also the shape Anthropic wants for the parallel case.
Why this is worth a post
If you pointed an OpenAI SDK at the Gateway before 9 September and got a 400, it was us, and the error you saw did not say so. It works now. The wider consequence is on the billing side: almost no inference ran for three months, which is how every plan stayed underwater at its own advertised limit without anyone noticing.
What the Gateway returns on a refusal, and which of them are worth retrying, is in Errors & retries.
All posts


