Deterministically repairs the single most common way an LLM breaks otherwise-valid JSON:
a double quote or raw control character left unescaped inside a string value.
Why this exists
Models embed rich markdown in string fields — mermaid diagrams, HTML mockups, code samples —
and reliably escape most of it. A single missed quote inside a 25KB response invalidates the
whole document. Nothing else in the repair chain recovers that: JSON5's leniency covers trailing
commas, comments and unquoted keys, but an unescaped " terminates a string in JSON5 exactly as
it does in JSON. The remaining fallback is an LLM round-trip on the full payload, which is slow,
costly, and itself unreliable at that size.
How it works
Purely error-driven, one character per pass:
JSON.parse the text and read the failure offset from the thrown error.
Scan backwards from that offset for the character that ended the string early.
Escape that one character.
Re-parse. Repeat until it parses or a stopping condition trips.
Every pass is validated by a real parse, so this never "pattern matches" its way to a wrong
answer the way a global regex rewrite would. It converges in one pass per offending character
(about two per quoted mermaid label) and gives up rather than guessing when it cannot make
progress.
Safety
This can, in principle, produce valid-but-wrong JSON: escaping a quote that legitimately ended a
string would merge two pieces of structure. Three properties keep that in check — it only runs
after a parse has already failed (so a correct document is never touched), it only ever adds
escapes and never deletes or reorders content, and it reports every offset it changed so callers
can log, audit, or schema-check the result before trusting it. Callers holding an expected shape
should validate against it; a wrong guess almost always fails shape validation.
Deterministically repairs the single most common way an LLM breaks otherwise-valid JSON: a double quote or raw control character left unescaped inside a string value.
Why this exists
Models embed rich markdown in string fields — mermaid diagrams, HTML mockups, code samples — and reliably escape most of it. A single missed quote inside a 25KB response invalidates the whole document. Nothing else in the repair chain recovers that: JSON5's leniency covers trailing commas, comments and unquoted keys, but an unescaped
"terminates a string in JSON5 exactly as it does in JSON. The remaining fallback is an LLM round-trip on the full payload, which is slow, costly, and itself unreliable at that size.How it works
Purely error-driven, one character per pass:
JSON.parsethe text and read the failure offset from the thrown error.Every pass is validated by a real parse, so this never "pattern matches" its way to a wrong answer the way a global regex rewrite would. It converges in one pass per offending character (about two per quoted mermaid label) and gives up rather than guessing when it cannot make progress.
Safety
This can, in principle, produce valid-but-wrong JSON: escaping a quote that legitimately ended a string would merge two pieces of structure. Three properties keep that in check — it only runs after a parse has already failed (so a correct document is never touched), it only ever adds escapes and never deletes or reorders content, and it reports every offset it changed so callers can log, audit, or schema-check the result before trusting it. Callers holding an expected shape should validate against it; a wrong guess almost always fails shape validation.