aillmjsondebugging

How to Fix Broken JSON from LLM Responses

·9 min read·AI & JSON

Why LLM JSON breaks

Even with JSON mode, you will occasionally receive output that JSON.parse() rejects — usually from truncation, an older model, or a prompt that did not constrain the format. The failures are remarkably predictable, which means most can be repaired automatically.

The seven common breakages

ProblemExampleFix
Markdown fences`json {…} `Strip leading/trailing fences
Preamble textHere is the JSON: {…}Slice from first { or [
Trailing comma{"a": 1,}Remove comma before }/]
Single quotes{'a': 1}Convert to double quotes
Comments{"a": 1 // note}Strip // and /* */
Unterminated string{"a": "helTruncation — re-request or close string
Python literals{"a": True, "b": None}Map True/False/None to true/false/null

A defensive parser

typescript
function repairJson(raw: string): string {
  let s = raw.trim();

  // 1. Strip Markdown fences
  s = s.replace(/^\`\`\`(?:json)?\n?/i, "").replace(/\n?\`\`\`$/i, "");

  // 2. Slice to the first JSON token
  const start = s.search(/[{[]/);
  if (start > 0) s = s.slice(start);

  // 3. Python-style literals -> JSON
  s = s.replace(/\bTrue\b/g, "true")
       .replace(/\bFalse\b/g, "false")
       .replace(/\bNone\b/g, "null");

  // 4. Remove trailing commas
  s = s.replace(/,(\s*[}\]])/g, "$1");

  return s;
}

function safeParse(raw: string) {
  try { return JSON.parse(raw); }
  catch { return JSON.parse(repairJson(raw)); }
}

This handles the majority of real-world cases. For single quotes and comments, the safest approach is a tolerant parser (such as JSON5) rather than fragile regex — quotes inside string values make naive replacement dangerous.

typescript
import JSON5 from "json5";
// JSON5 tolerates comments, single quotes, trailing commas, and unquoted keys
const data = JSON5.parse(repairJson(raw));

When repair is the wrong answer

Some failures should not be patched over:

  • Truncation. An unterminated string means the response was cut off — you are missing data. Increase max_tokens, or split the task, and re-request.
  • Wrong shape. If the JSON parses but has the wrong fields, repair will not help. Validate with a schema and re-prompt.
  • Hallucinated data. Valid JSON full of invented values is worse than a parse error because it fails silently. Always validate semantics, not just syntax.

Preventing breakage in the first place

  • Use the provider's structured-output / tool-use mode.
  • Explicitly forbid Markdown: "Respond with raw JSON only."
  • Prefill the assistant turn with { where supported.
  • Keep outputs small enough to avoid truncation.
  • Set temperature low for extraction tasks.

Debugging a stubborn response

When a payload still will not parse, do not squint at it — paste it into a formatter or auto-repair tool. A good tool highlights the exact line and column where parsing failed, so a missing brace 400 characters in becomes obvious instantly.

Frequently asked questions

Use a tolerant parser (JSON5) for structural quirks like comments and single quotes. Reserve regex for clearly safe transforms like stripping fences and trailing commas.

For non-critical extraction, yes — paired with schema validation. For anything financial or destructive, prefer re-requesting a clean response over guessing.

Almost always truncation: the model hit the token limit. Raise max_tokens or reduce what you ask for in a single call.

Try JSON Fixer

Auto-repair trailing commas, fences, single quotes and more — instantly.