# OpenAI JSON mode gave you broken JSON: use strict schemas, not just json_object
## The symptom
You set `response_format: {"type": "json_object"}` and the output still fails parsing, or it parses but fields are missing, mistyped, or invented. JSON mode promises valid JSON syntax. It does not promise your schema.
## Confirm the cause
- **Parse failure:** the model wrapped JSON in prose or fences despite JSON mode, or emitted a truncated object. Inspect the raw string before parsing.
- **Wrong shape:** JSON mode has no schema enforcement. The model guesses your fields from the prompt, and guesses drift.
- **Silent refusal:** on sensitive topics the model may refuse inside the JSON. With plain JSON mode that refusal is just text you must detect yourself.
## The fix
Move to Structured Outputs: `response_format: {"type": "json_schema", "json_schema": {"name": ..., "strict": true, "schema": {...}}}`. What changes:
- **Type safety without retry loops.** Output matches your schema or the call fails. No more parse-then-patch code.
- **Explicit refusals.** Safety-based refusals become programmatically detectable instead of hiding in a string field.
- **Simpler prompts.** The schema carries the format, so you stop begging for it in prose.
Keep two habits: validate the parsed object against your schema on your side (cheap defense in depth), and handle the refusal case explicitly instead of crashing on it.
## Verify the fix
Send the previously failing prompt with a strict schema and confirm it validates first try across a batch of runs, not just once. Log schema-validation failures as a metric; zero for a week means the migration worked.