Ask ChatGPT, Claude, or almost any large language model for JSON, and most of the time you get back something that looks right and parses fine. Often enough, though, JSON.parse throws instead, and the object you were expecting is nowhere to be found. This is common enough that it has its own name in a few developer communities: “LLM JSON,” meaning JSON that reads like the real thing but fails strict parsing.
Why LLM output breaks JSON in the first place
Language models generate text one token at a time, predicting what’s likely to come next based on patterns in their training data. They are very good at producing JSON-shaped text and not actually running a JSON validator against their own output. A few specific failure patterns show up over and over.
Markdown code fences. Ask for JSON in a chat interface and you’ll often get it wrapped in a fenced code block: three backticks, the word json, your data, three more backticks. That’s helpful for display in a chat window and invalid the moment you copy the whole block and try to parse it as JSON - the fence characters and the language tag aren’t part of the JSON grammar.
Leading or trailing prose. A model that’s been asked a question sometimes answers with a sentence before the JSON (“Here’s the JSON you requested:”) or a note after it. Either one breaks a strict parse, since valid JSON is a single self-contained value with nothing else around it.
Trailing commas. JavaScript object literals tolerate a comma after the last item in an array or object. JSON does not. Models trained heavily on JavaScript code sometimes carry that habit into JSON output.
Single quotes instead of double quotes. Same root cause - Python dictionaries and JavaScript objects both accept single-quoted strings; JSON requires double quotes for every string and every key.
Truncation. This is the one that’s hardest to work around by hand. If a response hits a token limit mid-object, you get JSON that’s missing its closing brackets - sometimes several levels of them, depending on how deep the model was when it ran out of budget.
Unquoted keys and comments. Less common, but they show up in prompts where the model is echoing back something closer to a JavaScript object literal or a JSON-with-comments config format than strict JSON.
How to spot exactly what’s wrong
The unhelpful version of a JSON parse error is a message like “Unexpected token in JSON at position 412.” Knowing the failure exists doesn’t tell you where it is or what to do about it.
Paste the output into Jsontify’s JSON Validator and you get the line and column of the first problem, plus a plain description of what’s wrong - “Trailing comma before },” “Object keys must use double quotes,” and so on - instead of a raw parser exception. That’s usually enough to fix a single small issue by hand. For anything more involved, or for output that’s broken in more than one way at once, use Repair instead.
Fixing it with Repair
Paste the broken JSON into Jsontify and click Repair. The tool runs a dedicated repair pass that handles the patterns above automatically - trailing commas, single-quoted strings, unquoted keys, code fences and stray text around the JSON, and (where the input allows it) a best-effort close of a truncated document. The result replaces your document in a single undoable step, so if the repair isn’t what you wanted, Cmd+Z (or Ctrl+Z) gets you back to exactly what you pasted.
This runs entirely client-side: parsing and repairing both happen in your browser, in a background worker - nothing is uploaded to our servers, which is worth knowing when the JSON in question is a real API response or log line you’d rather not paste into a random server-side tool.
When repair can’t fully save it
Repair fixes syntax problems - the JSON shape is there, just malformed. It can’t invent data that was never generated in the first place. If a response was cut off badly enough that an entire object or array is missing (not just its closing bracket), the best fix is upstream: ask the model to continue from where it stopped, or increase the response’s token limit before generating again.
Preventing it next time
A few habits cut down on how often this happens in the first place:
- Ask explicitly for “JSON only, no explanation and no markdown code fences” in the prompt.
- If the API you’re using supports a structured-output or JSON mode, use it - it constrains generation to valid JSON at the model level instead of hoping the model follows instructions.
- For long responses, ask for smaller chunks rather than one large nested object, so a token-limit cutoff loses less if it happens.
None of these fully eliminate the problem, which is exactly why a quick repair step is worth keeping in your workflow rather than debugging the same handful of syntax errors by eye every time.