
OpenRouter Structured Output Broke Before Translation Quality Did — 3 Layers of Defense for Production
The first production incident wasn't a bad translation. It was a Markdown code fence wrapping the JSON response. One day, error notifications flooded in. The UI was rendering blank blocks where translations should have been. The cause? The model had quietly started being "helpful" by wrapping its JSON responses in json ... fences. JSON.parse() choked immediately, and the translation feature went down — not because of bad translations, but because of three backticks. This article walks through the exact defense system I built to stabilize structured output from the OpenRouter API in production, in the order the failures surfaced. The main topic is malformed JSON responses. I also cover retry/fallback and language detection, but JSON handling is where most of the engineering hours went. TL;DR The Core Issue: LLM translation quality doesn't matter if JSON.parse() fails. Markdown code fences and truncation will break your app before bad translations do. The Safe Baseline: json_object + res
Continue reading on Dev.to JavaScript
Opens in a new tab




