It started, as these things always do, at 1 AM. I had asked an LLM to generate a chunk of structured data — a few hundred lines of JSON for a seed script — and it came back looking perfect. I pasted it into my project, hit run, and Node handed me this:
Unexpected token } in JSON at position 812
Position 812. Thanks, Node. That narrowed it down to... somewhere in the file.
The real pain: AI output that looks like JSON
If you've worked with LLMs for more than a week, you know this ritual. The output looks pristine in the chat window, but it's a minefield. In my experience, broken AI-generated JSON fails for one of five reasons:
- Markdown code fences — the model wraps everything in triple backticks. Those fences are not JSON.
-
Trailing commas —
{ "id": 1, }. The model learned JavaScript's looser habits. -
Unquoted keys —
{ id: 1 }works in JS, dies inJSON.parse. -
Smart quotes — some chat UIs turn
"into “ and ”. Invisible until it breaks. -
Comments — models love adding
// like thisto "helpful" config output. JSON doesn't allow them.
Here's a typical specimen — spot the three violations before you scroll on:
{
"model": "seed-generator-v3",
"items": [
{ "id": 1, "name": "Ada", },
{ id: 2, "name": "Grace" },
],
// generated 2026-10-15
}
(Answer: trailing commas after "Ada", and },, the unquoted key id, and the // comment.)
Each one is a five-second fix. Finding it among 500 lines is the part that takes an hour.
Why the usual fixes are annoying
The obvious move is JSON.parse in a scratch file and reading the error message. But native error messages are famously unhelpful — a position number with no context, or in some engines no position at all. Online validators are the next stop, and here's where I got picky: most of them send your paste to a server. When your JSON contains a staging API key or a chunk of real user data, that's a hard no for me.
The third option — hand-rolling a fixer script — is what I actually did for a while. Here's the tiny trick that made JSON.parse errors bearable:
function pinpointError(raw) {
try {
JSON.parse(raw);
return null; // valid!
} catch (err) {
const m = /position (\d+)/.exec(err.message);
const pos = m ? Number(m[1]) : 0;
// show 60 chars of context around the failure point
return raw.slice(Math.max(0, pos - 40), pos + 20);
}
}
This one snippet turned "position 812" into the actual offending character with context. Game changer. But I still had to strip code fences by hand, regex trailing commas myself, and — the sketchy part — I once "fixed" a payload by running a regex that ate a comma inside a string value. That was the moment I decided repair tools need a preview before apply step, or they're just a fancier way to corrupt data.
So I built the tool I kept wishing existed
Full disclosure: I built this tool — it's a browser-local JSON syntax validator and debugging workspace. Everything I'm about to describe, I use myself whenever an API or an LLM hands me suspect JSON. Here's what the workflow looks like:
1. Paste and validate. No account, no upload. Paste in the tool and it checks syntax immediately, entirely inside your browser tab. You can verify the "no upload" claim by opening the Network panel — nothing leaves the page.
2. Read a location-aware error message. Instead of a bare position number, you get the line, the column, and the surrounding context. Plus two things plain validators skip: duplicate-key warnings (technically valid JSON, but parsers silently keep only the last value — a silent data-loss bug) and interoperability notes that flag constructs which parse in one language but behave differently in another.
3. Use the safe repair preview. This is the part I care about most. The preview handles the common copy-and-paste fixes — code fences, trailing commas, quote normalization, unquoted keys — and shows you the resulting document before anything is applied. The fixes stay in the preview until you explicitly choose to use them. No regex roulette on your own data.
4. Validate against a schema, still locally. If you're generating fixtures for an API, you can paste an inline JSON Schema and validate against it in the same tab. Remote $ref values are never fetched, so there's no network round-trip and no leaking your schema.
The whole flow — paste, locate, preview-repair, schema-check — takes about three minutes for the typical "the model gave me 400 lines and one comma is wrong" case. You can try it here: JSON Validator Online.
The takeaway
AI models will keep emitting almost-JSON for the foreseeable future — they generate tokens, not grammars, so trailing commas and code fences are features of how they write, not bugs in your prompt. The fix isn't better prompting; it's a repair workflow that assumes the input is hostile: validate locally, see the exact error location, preview every repair before applying it, and never upload data you wouldn't email to a stranger.
What's the weirdest broken-JSON-from-AI story you've hit? The fence-in-a-fence? A smart quote hiding in a 2,000-line file? Drop it in the comments — I want to know I'm not alone in this.
Top comments (0)