I had a system prompt that ended with: Reply with only a JSON object. Do not include code fences. Do not include explanation.
That should be enough. It is not.
Over a week of structured-output calls (12,400 of them, mostly Claude Sonnet 4.5 and 4.7), I logged how often the response was actually parseable as JSON on the first serde_json::from_str attempt. Result: 86.0%. The other 14% had at least one of these problems:
json ... wrappers (most common, about 9.3% of total)
Leading or trailing prose ("Here is the JSON you asked for:")








