Valid JSON is strict. Humans and language models are not. You end up with a blob that is almost JSON: a trailing comma after the last property, single quotes instead of double, a comment someone swore was fine, an object cut off mid-stream. JSON.parse throws, your pipeline stops, and you are staring at a bracket-counting exercise on a deadline.
This guide walks through the errors you actually hit, how to fix each one by hand, the libraries that automate it, and why LLM output breaks in its own special ways. At the end there’s a one-call option for when you’d rather not maintain a repair function forever.
The Six Ways JSON Breaks (and the Fix for Each)
1. Trailing commas
The single most common one. JSON, unlike JavaScript, forbids a comma after the last element.
{ "a": 1, "b": 2, } // ✗ invalid
{ "a": 1, "b": 2 } // ✓ fixed
Fix: delete the comma before every } and ]. A regex like /,(\s*[}\]])/g → $1 handles it in bulk.
2. Single quotes and smart quotes
JSON strings must use straight double quotes. Copy from Word, Slack, or Notion and you often get curly “smart” quotes; write it like JavaScript and you get single quotes.
{ 'name': 'Ada' } // ✗ single quotes
{ “name”: “Ada” } // ✗ smart quotes
{ "name": "Ada" } // ✓ straight double quotes
Fix: replace ‘ ’ “ ” with ", but be careful not to clobber apostrophes inside string values, which is exactly why a real parser beats a blind find-and-replace.
3. Unquoted keys
{ name: "Ada" } // ✗ key not quoted
{ "name": "Ada" } // ✓
Fix: quote every key. This is valid JavaScript and valid JSON5, but not valid JSON.
4. Comments
JSON has no comments. A // like this or /* like this */ anywhere in the payload is a hard error. Fix: strip them, but not if the // lives inside a URL string, another parser-vs-regex trap.
5. Truncated / cut-off output
The classic LLM failure: the model hit its token limit mid-object and the string just… stops. Fix: close the open brackets, or (better) re-request with a higher max_tokens. Repair can only guess at data that was never generated.
6. Prose wrapped around the JSON
“Sure! Here is your JSON:” followed by a fenced code block. Fix: extract the substring between the first { (or [) and its matching close, and discard the rest.
Don’t Hand-Roll It: The Tools That Do This
For anything beyond a one-off, use a library built for lenient parsing instead of a stack of regexes:
- JavaScript / TypeScript: the
jsonrepairnpm package, or parse as JSON5 which natively allows comments, trailing commas, and unquoted keys. - Python: the
json-repairpackage, ordemjson3for forgiving parsing. - Command line:
jqwon’t fix malformed input, but it’s the fastest way to validate and pretty-print once the syntax is clean.
Why LLM JSON Breaks Differently
Language models generate JSON token by token with no guarantee the result parses. They over-run their token budget, wrap output in explanation, escape strings inconsistently, and occasionally invent a trailing comment. The durable fix is upstream: use your model’s structured-output or JSON mode (constrained decoding), which forces syntactically valid output at generation time. Repair is the safety net for when you can’t control the generator: a third-party API, an older model, a tool you don’t own.
Repair JSON as a $1 / x402 call
When you’d rather call an endpoint than maintain a repair function, JSON repairer takes the broken string and returns valid JSON when repair is possible. Humans pay $1 per call in the browser; agents call POST https://gate402.app/v1/json-repair, handle the 402 Payment Required, pay, and retry. It is the same pattern across the whole Gate402 utility set. Handy inside an agent loop that emits broken JSON every few calls and needs to self-heal without a human.
When Repair Is the Wrong Tool
If the model omitted half the schema, “repair” may invent structure you should not trust. Prefer repair for syntax damage, then always validate against your schema (JSON Schema, Zod, Pydantic) afterward. Garbage semantics (missing required fields, wrong types) need a better prompt or structured output, not a syntax patch.
Quick answers
Is repaired JSON safe to trust?
For syntax fixes (commas, quotes, brackets), yes. For truncated or semantically incomplete data, no. Validate against a schema before you rely on it.
How do I stop the LLM producing broken JSON in the first place?
Use the provider’s structured-output / JSON mode, give it a schema, and set a max_tokens high enough that it doesn’t truncate.
What about CSV that needs to become JSON?
Different job. That’s the CSV ↔ JSON tool.
What to do next time
Don’t hand-edit trailing commas in a production agent path. Fix the generator where you can (structured output), use a real lenient parser where you can’t, and validate the result against a schema before trusting it. When you want that as an endpoint instead of a gist you maintain forever, repair JSON for $1, or over x402 for agents.
