All articles

JSON Repair: why JSON breaks and how to fix it

"Broken" JSON is a common problem: the file looks almost right, but a parser refuses to read it. The cause is usually a small syntax slip — and increasingly often, that slip comes from a tool rather than a person.

Common causes of invalid JSON

  • A trailing comma before a closing bracket — {"a": 1,} — which some languages (like JavaScript) tolerate but a strict JSON parser won't.
  • Single quotes instead of double quotes — common when copying from a JavaScript object literal, or from Node's console.log output, which prints objects with single quotes by default.
  • Unquoted keys{name: "Alex"} instead of {"name": "Alex"}, also valid in JS but not in JSON.
  • Comments — the JSON spec doesn't allow comments at all, unlike JSON5 or JSONC.
  • Truncated output — if an API response or log file gets cut off midway, the document is left unclosed.

The newest source of broken JSON: language models

A growing share of "JSON that won't parse" today comes from LLM output rather than hand-typed code. A model asked to "return JSON" will frequently wrap it in a markdown code fence, add a trailing comma out of JavaScript habit, insert an explanatory sentence before the opening brace, or truncate the response mid-object when it hits a token limit — the object simply stops, unclosed, exactly where generation ended. None of that is a human typo, but the fix is the same: strip the wrapper text, close what's open, drop what's extra.

How automatic repair works

A JSON repair tool applies heuristics: adding missing quotes, removing trailing commas, closing unclosed brackets based on context. This works well for common, typical mistakes, but it's not magic — the tool can't guess what value was intended if the data is more seriously corrupted.

The limits of what's possible

Automatic repair fixes syntax, not semantics. If a field is missing entirely, or a value is logically (rather than syntactically) wrong, the tool won't catch that — the result still needs a manual check, especially when the source was a truncated LLM response rather than a hand-edited file.

When the repair is ambiguous

Some corruption has several equally plausible fixes. A truncated string like {"a": 1, "b": 2 can simply be closed with a bracket — losing data if another field was actually intended. In such cases, the repair heuristic makes a "least destructive" guess, most often just closing the open brackets, but that's a guess, not a guarantee of restoring the original intent.

Try the tool