devtools.codes

Why structured output fails validation

Your tool input is processed locally in your browser and is not intentionally uploaded to our servers. Advertising and analytics providers may still process normal page, device, cookie and network information.

Structured output fails for a small number of recurring reasons, and knowing which one you are looking at usually tells you whether to change the schema or the prompt.

The most common is a type mismatch that looks correct to a human. A model asked for a number frequently returns the string "0.87". The JSON is well formed and the value is right, but a strict validator rejects it. Either coerce on your side deliberately, or make the description explicit that the value must be an unquoted number.

The second is invented properties. Models add fields that seem helpful — a confidence score, an explanation, a reasoning trace — that your schema never declared. Without additionalProperties set to false these pass validation silently and flow into your code unnoticed. With it set, they become a visible error, which is almost always what you want.

The third is a missing required field, usually because the model had nothing sensible to put there. This is a prompt problem rather than a schema problem: if a field is genuinely optional for some inputs, marking it required guarantees intermittent failures.

The fourth is wrapping. The payload is correct but arrives inside a markdown code fence with a sentence of preamble. This is a parsing problem, not a validation one, and it is solved by extracting the JSON rather than by changing the schema.

The fifth is enum drift, where a model returns a plausible value outside your allowed set — "very positive" when you defined positive, neutral and negative. Tightening the description and listing the allowed values in the prompt as well as the schema usually resolves it.

A practical rule: validate every response in development, log which of these five categories each failure falls into, and you will know within a day whether your problem is the schema, the prompt or the model.

More on why structured output fails validation

Should I coerce a string number or reject it?

Decide once and apply it everywhere. Coercing quietly is convenient until a value like "1,200" or "N/A" arrives and coercion produces something wrong rather than something failed. If you do coerce, do it in a named step you can log, so a surprising value surfaces as a decision your code made rather than as a mystery downstream.

Does additionalProperties: false break anything?

It breaks responses that contain fields you never declared, which is the point. The cost is that adding a field to your prompt without adding it to the schema now fails loudly. That is a better failure than the alternative, where an undeclared field passes validation and flows into code that has never seen it.

Is a markdown code fence around the JSON a validation failure?

No, it is a parsing failure that happens before validation runs. The payload inside the fence may be perfectly valid. Extract the JSON first, then validate. Changing the schema will not help, and tightening it in response to this failure is the most common wasted afternoon in structured output work.

How do I stop a model inventing enum values?

List the allowed values in both the schema and the prompt, and keep them short and unambiguous. An enum in the schema constrains what passes validation; the same list in the prompt reduces how often the model produces something else in the first place. Values that overlap in meaning, such as positive and very positive, invite drift.

The tool behind this, and related guides