Why AI-Generated JSON Is Always Broken — and How to Fix Every Error

You asked ChatGPT, Claude, or Gemini to generate some JSON. It looks perfect. You copy it into your code, call JSON.parse(), and — crash. SyntaxError: Unexpected token. This is not a coincidence. AI language models have systematic, predictable blind spots with JSON that stem from how they were trained. This guide explains exactly why it happens and gives you every tool you need to detect and fix it automatically.

#1

Trailing commas — the most common AI JSON error by far

8

distinct error patterns AI models consistently get wrong

100%

of AI JSON errors can be auto-detected and fixed

< 1s

to fix all errors with an AI JSON Error Explainer tool

1

Why AI Models Generate Broken JSON — The Root Cause

The answer is surprisingly simple: AI language models were trained on the entire public internet, which contains vastly more JavaScript code than it does JSON data files. JavaScript object literals look almost identical to JSON but follow different rules — they allow trailing commas, single quotes, unquoted keys, comments, undefined, NaN, and Infinity. When a model generates “JSON”, it is actually blending JavaScript object syntax with JSON syntax, because its training data did not cleanly separate the two.

Additionally, AI models generate text token-by-token, predicting what comes next based on probability. The last comma in a list followed by a closing brace is a common JavaScript pattern, so the model generates it — even though it is illegal in JSON. The model has no JSON validator running internally. It cannot check its own output against the RFC 8259 specification.

Trained on JavaScript, not JSON

The internet has billions of lines of JavaScript code with trailing commas, single quotes, and unquoted keys. AI models learn that {name: "Alice",} is a normal pattern — because in JS it is. JSON rejects it entirely.

Token-by-token generation with no validator

LLMs generate one token at a time. There is no internal JSON validator checking the output. A model cannot "go back" to remove a trailing comma it just predicted as the next natural token.

Python dict confusion

Models trained on Python code learn True, False, None as boolean/null literals. When generating JSON for a Python context, they revert to Python capitalization — which is invalid in JSON.

Prompt length pressure

When generating long JSON, models sometimes cut corners on well-formed structure to fit within context windows, producing unclosed brackets, extra commas, or truncated values near the end.

2

The 8 AI JSON Error Patterns — With Examples and Fixes

Pattern #1 — Trailing Commas (Most Common)

Every AI model produces trailing commas in JSON. It is the single most frequent error across ChatGPT, Claude, Gemini, and every other LLM. A trailing comma appears after the last element in an array or object, before the closing bracket. Standard JSON parsers reject it immediately.

AI output — trailing commas (invalid)

❌ Bad
// ❌ Classic AI output — trailing commas everywhere
{
  "name": "Alice Chen",
  "age": 30,
  "roles": [
    "admin",
    "editor",
  ],
  "settings": {
    "theme": "dark",
    "notifications": true,
  },
}

Valid JSON — commas removed before ] and }

✅ Good
// ✅ Valid JSON — no trailing commas
{
  "name": "Alice Chen",
  "age": 30,
  "roles": [
    "admin",
    "editor"
  ],
  "settings": {
    "theme": "dark",
    "notifications": true
  }
}

Pattern #2 — JavaScript-Only Values (undefined, NaN, Infinity)

JavaScript has three special values that have no equivalent in JSON: undefined,NaN, and Infinity. AI models trained on JavaScript code learn these as valid values. JSON only allows: string, number, boolean (true/false), null, array, and object. Any other value is illegal.

JS-only values — not valid JSON

❌ Bad
// ❌ AI output with JS-only values
{
  "user": "Bob",
  "score": NaN,
  "bonus": Infinity,
  "pendingAction": undefined,
  "ratio": -Infinity
}

Replace with null or meaningful defaults

✅ Good
// ✅ Fixed — all replaced with null
{
  "user": "Bob",
  "score": null,
  "bonus": null,
  "pendingAction": null,
  "ratio": null
}

// Or replace with meaningful fallbacks:
{
  "user": "Bob",
  "score": 0,
  "bonus": 999999,
  "pendingAction": null,
  "ratio": -1
}

Pattern #3 — Python Capitalised Booleans (True, False, None)

This happens almost exclusively when the prompt asks for JSON in a Python context, or when the model was heavily fine-tuned on Python code. Python uses True, False, and None — JSON uses true, false, and null. One capital letter breaks the entire parse.

Python-style literals — invalid in JSON

❌ Bad
// ❌ Python-style literals — will fail JSON.parse() and json.loads()
{
  "active": True,
  "verified": False,
  "metadata": None,
  "count": 5
}

JSON literals are always lowercase

✅ Good
// ✅ Correct JSON literals — always lowercase
{
  "active": true,
  "verified": false,
  "metadata": null,
  "count": 5
}

// If using Python to generate JSON:
import json
data = {"active": True, "verified": False, "metadata": None}
json_string = json.dumps(data)  # ✅ Produces lowercase true/false/null
# ❌ Never: str(data)  → produces Python repr with True/False/None

Pattern #4 — Single-Quoted Strings

AI models frequently output single-quoted strings, especially when the prompt uses examples with single quotes, or when generating JSON that resembles a Python or JavaScript context. JSON requires all strings — both keys and values — to be enclosed in double quotes.

Single quotes — invalid JSON

❌ Bad
// ❌ Single quotes — invalid in JSON
{
  'name': 'Charlie',
  'tags': ['developer', 'python'],
  'city': 'New York'
}

Double quotes — the only valid option

✅ Good
// ✅ Double quotes — required by JSON spec (RFC 8259 §7)
{
  "name": "Charlie",
  "tags": ["developer", "python"],
  "city": "New York"
}

// Auto-fix: replace single-quoted strings carefully:
const fixed = text.replace(/'([^'\\]|\\.)*'/g, m =>
  '"' + m.slice(1, -1).replace(/\\'/g, "'").replace(/"/g, '\\"') + '"'
);

Pattern #5 — Unquoted Object Keys

In JavaScript, object keys do not need quotes: {name: "Alice"} is valid JavaScript. In JSON, every key must be a quoted string: {"name": "Alice"}. AI models confuse the two, particularly when generating JSON that represents a JavaScript object.

Unquoted keys — invalid JSON

❌ Bad
// ❌ Unquoted keys — JS object literal syntax, not JSON
{
  id: 1,
  name: "Diana",
  active: true,
  createdAt: "2026-01-15"
}

Quoted keys — JSON requires strings for all keys

✅ Good
// ✅ All keys double-quoted — valid JSON
{
  "id": 1,
  "name": "Diana",
  "active": true,
  "createdAt": "2026-01-15"
}

// Auto-fix regex (handles simple cases):
const fixed = text.replace(
  /([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)(\s*:)/g,
  (_, before, key, after) => before + '"' + key + '"' + after
);

Pattern #6 — JavaScript Comments

When generating configuration files or annotated JSON, AI models frequently include JavaScript comments (// line comment or /* block comment */). Comments are explicitly forbidden by the JSON specification. The model knows what JSONC is but generates standard JSON mixed with comments because its training data blended both formats.

Comments are not valid JSON

❌ Bad
// ❌ Comments in JSON — will fail every standard parser
{
  // Database connection settings
  "host": "localhost",
  "port": 5432, /* default PostgreSQL port */
  "database": "production",
  "ssl": true // require SSL in production
}

Remove all comments for valid JSON

✅ Good
// ✅ No comments — pure JSON
{
  "host": "localhost",
  "port": 5432,
  "database": "production",
  "ssl": true
}

// To strip comments before parsing:
const stripped = jsonText
  .replace(/\/\/[^\n]*/g, '')        // strip line comments
  .replace(/\/\*[\s\S]*?\*\//g, ''); // strip block comments
const parsed = JSON.parse(stripped);

Pattern #7 — Unclosed or Mismatched Brackets

For large JSON structures, AI models sometimes fail to close all brackets — particularly when the generated output is near the context limit. The model predicts the next token but loses track of nesting depth over long sequences. Mismatched brackets (using } where] is expected) also occur when the model confuses array vs. object context.

Unclosed / mismatched brackets

❌ Bad
// ❌ Unclosed bracket — missing ] at the end
{
  "users": [
    {"id": 1, "name": "Eve"},
    {"id": 2, "name": "Frank"}
  ,
  "total": 2
}
// ← The [ for "users" is never closed with ]

// ❌ Mismatched bracket — ] used where } expected
{
  "items": [1, 2, 3},
  "count": 3
]

Every opener has a matching closer of the correct type

✅ Good
// ✅ Properly closed and matched brackets
{
  "users": [
    {"id": 1, "name": "Eve"},
    {"id": 2, "name": "Frank"}
  ],
  "total": 2
}

// ✅ Matching bracket types
{
  "items": [1, 2, 3],
  "count": 3
}

Pattern #8 — Invalid Number Formats (Leading Zeros, Plus Signs)

JSON has strict number formatting rules. Leading zeros are forbidden (except 0 itself):007 must be 7. A leading plus sign is also illegal: +42must be 42. AI models sometimes generate these forms when copying number patterns from code or configuration contexts where they are valid (C, Python, YAML).

Invalid: leading zeros and plus signs

❌ Bad
// ❌ Invalid number formats in JSON
{
  "timeout": 030,
  "port": 08080,
  "priority": +5,
  "temperature": +0.7
}

Valid JSON numbers

✅ Good
// ✅ Valid JSON number formats
{
  "timeout": 30,
  "port": 8080,
  "priority": 5,
  "temperature": 0.7
}

// JSON number rules (RFC 8259 §6):
// ✅ 0, -0, 1, -1, 3.14, 1e10, 1.5e-3
// ❌ 007 (leading zero), +5 (plus sign), 1. (trailing dot), .5 (no leading digit)
3

How to Prompt AI Models for Valid JSON

You can dramatically reduce AI JSON errors by crafting better prompts. The model responds to explicit constraints — telling it exactly what rules to follow pushes it to comply more consistently.

textEffective prompts for valid JSON output
# Prompt template that minimizes AI JSON errors:

"Generate a JSON object representing a user profile.
IMPORTANT JSON RULES — follow these exactly:
- All keys must be double-quoted strings
- All string values must use double quotes (not single quotes)
- No trailing commas after the last element in arrays or objects
- Use lowercase true, false, null (NOT True/False/None/undefined/NaN)
- No // comments or /* */ comments
- No leading zeros in numbers, no + prefix on positive numbers

Return ONLY the raw JSON object with no explanation, no markdown
code fences, and no surrounding text."

# Even better — provide an example of the shape:
"Follow this exact structure:
{
  "id": 1,
  "name": "example",
  "active": true,
  "tags": ["a", "b"]
}
Your JSON must be parseable by JSON.parse() without any modification."

Ask the model to self-validate

Add this to your prompt: “After generating the JSON, verify it is RFC 8259 compliant by mentally checking: (1) no trailing commas, (2) all strings double-quoted, (3) only true/false/null as special literals, (4) all brackets matched.” This self-correction step catches many common errors before you receive the output.
4

Programmatic Validation — Catch AI JSON Errors in Your Pipeline

If you are building a system that regularly consumes AI-generated JSON (an API wrapper, an LLM orchestration pipeline, a data extraction tool), you should validate and repair JSON automatically rather than relying on prompts alone.

javascriptProduction-grade AI JSON repair pipeline
// Step 1: Strip markdown code fences (AI often wraps JSON in ```json...```)
function stripMarkdownFences(text) {
  return text
    .replace(/^```(?:json)?s*/i, '')  // remove opening fence
    .replace(/s*```s*$/i, '')          // remove closing fence
    .trim();
}

// Step 2: Strip JavaScript comments
function stripComments(text) {
  return text
    .replace(///[^
]*/g, '')
    .replace(//*[sS]*?*//g, '');
}

// Step 3: Fix Python-style literals
function fixPythonLiterals(text) {
  return text
    .replace(/(?<!["w])(True)(?!["w])/g, 'true')
    .replace(/(?<!["w])(False)(?!["w])/g, 'false')
    .replace(/(?<!["w])(None)(?!["w])/g, 'null');
}

// Step 4: Fix JS-only values
function fixJsValues(text) {
  return text
    .replace(/:s*undefined/g, ': null')
    .replace(/:s*NaN/g, ': null')
    .replace(/:s*-?Infinity/g, ': null');
}

// Step 5: Remove trailing commas
function fixTrailingCommas(text) {
  let prev;
  do { prev = text; text = text.replace(/,(s*[}]])/g, '$1'); }
  while (prev !== text);
  return text;
}

// Combined repair function
function repairAiJson(raw) {
  let text = stripMarkdownFences(raw);
  text = stripComments(text);
  text = fixPythonLiterals(text);
  text = fixJsValues(text);
  text = fixTrailingCommas(text);
  try {
    return { data: JSON.parse(text), error: null, fixed: text };
  } catch (e) {
    return { data: null, error: e.message, fixed: text };
  }
}

// Usage:
const { data, error, fixed } = repairAiJson(llmOutput);
if (error) {
  console.error('Could not repair JSON:', error);
  console.log('Repaired text was:', fixed);
} else {
  console.log('Parsed successfully:', data);
}
pythonPython — repair AI JSON output
import re
import json

def strip_markdown_fences(text: str) -> str:
    """Remove ```json...``` wrappers that AI models add."""
    text = re.sub(r'^```(?:json)?s*', '', text, flags=re.IGNORECASE)
    text = re.sub(r's*```s*$', '', text)
    return text.strip()

def strip_comments(text: str) -> str:
    text = re.sub(r'//[^
]*', '', text)
    text = re.sub(r'/*[sS]*?*/', '', text)
    return text

def fix_python_literals(text: str) -> str:
    """Replace Python True/False/None with JSON true/false/null."""
    text = re.sub(r'(?<!["w])(True)(?!["w])', 'true', text)
    text = re.sub(r'(?<!["w])(False)(?!["w])', 'false', text)
    text = re.sub(r'(?<!["w])(None)(?!["w])', 'null', text)
    return text

def fix_trailing_commas(text: str) -> str:
    prev = None
    while prev != text:
        prev = text
        text = re.sub(r',(s*[}]])', r'\1', text)
    return text

def repair_ai_json(raw: str) -> dict | list | None:
    text = strip_markdown_fences(raw)
    text = strip_comments(text)
    text = fix_python_literals(text)
    text = fix_trailing_commas(text)
    try:
        return json.loads(text)
    except json.JSONDecodeError as e:
        raise ValueError(f"Could not repair JSON: {e}") from e

# Usage:
data = repair_ai_json(llm_output)  # handles most AI JSON errors
5

Structured Output Mode — Force Valid JSON at the API Level

All major AI APIs now offer a “structured output” or “JSON mode” that constrains the model to produce syntactically valid JSON. This is the most reliable solution for production pipelines and should be your first choice.

javascriptOpenAI JSON mode and structured outputs
import OpenAI from 'openai';
const openai = new OpenAI();

// Method 1: JSON mode (guarantees valid JSON, any shape)
const completion = await openai.chat.completions.create({
  model: 'gpt-4o',
  response_format: { type: 'json_object' },  // ✅ Forces valid JSON
  messages: [
    { role: 'system', content: 'You always respond with valid JSON.' },
    { role: 'user', content: 'Generate a user profile for Alice Chen, age 30, roles: admin, editor.' },
  ],
});
const data = JSON.parse(completion.choices[0].message.content);

// Method 2: Structured outputs with JSON Schema (guarantees exact shape)
const completion2 = await openai.chat.completions.create({
  model: 'gpt-4o-2024-08-06',
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'user_profile',
      strict: true,
      schema: {
        type: 'object',
        properties: {
          name:   { type: 'string' },
          age:    { type: 'integer' },
          roles:  { type: 'array', items: { type: 'string' } },
          active: { type: 'boolean' },
        },
        required: ['name', 'age', 'roles', 'active'],
        additionalProperties: false,
      },
    },
  },
  messages: [{ role: 'user', content: 'Generate a user profile for Alice Chen.' }],
});
// Guaranteed to parse without errors AND match the schema exactly
const user = JSON.parse(completion2.choices[0].message.content);

OpenAI — JSON mode

Set response_format: { type: "json_object" }. Guarantees syntactically valid JSON but does not enforce shape. Works with gpt-4o, gpt-4-turbo, gpt-3.5-turbo-1106+.

OpenAI — Structured Outputs

Set response_format: { type: "json_schema", json_schema: {...} } with strict: true. Guarantees both valid JSON and matching schema. Available on gpt-4o-2024-08-06+.

Anthropic Claude — tool_use

Define a tool with an input_schema. Ask Claude to "call the tool" with the data. Claude's tool_use output is always valid JSON matching the schema you provided.

Google Gemini — responseMimeType

Set generationConfig.responseMimeType to "application/json" and provide responseSchema. Gemini will constrain its output to match the schema using constrained decoding.

6

Validating AI JSON Against a Schema

Even with JSON mode enabled, you should validate the structure of the parsed JSON. An AI model can produce {"age": "thirty"} — syntactically valid JSON but semantically wrong. JSON Schema validation catches type mismatches and missing fields.

javascriptRuntime JSON Schema validation with Zod
import { z } from 'zod';

// Define your expected shape with Zod
const UserSchema = z.object({
  id:        z.number().int().positive(),
  name:      z.string().min(1),
  email:     z.string().email(),
  roles:     z.array(z.enum(['admin', 'editor', 'viewer'])),
  active:    z.boolean(),
  createdAt: z.string().datetime().optional(),
});

type User = z.infer<typeof UserSchema>;

async function getAiGeneratedUser(prompt: string): Promise<User> {
  const rawJson = await callAiApi(prompt);

  // Step 1: repair common AI JSON errors
  const repairedText = repairAiJson(rawJson);

  // Step 2: parse JSON
  let parsed: unknown;
  try {
    parsed = JSON.parse(repairedText);
  } catch (e) {
    throw new Error(`AI returned unparseable JSON: ${e.message}`);
  }

  // Step 3: validate shape and types
  const result = UserSchema.safeParse(parsed);
  if (!result.success) {
    const issues = result.error.issues.map(i => `${i.path.join('.')}: ${i.message}`);
    throw new Error(`AI JSON failed schema validation: ${issues.join(', ')}`);
  }

  return result.data; // ✅ Fully typed, validated data
}

Never trust AI JSON blindly

Even with JSON mode enabled and a repair function applied, always validate structure and types before using AI-generated data. A model can generate {"user_id": "abc123"} when you need an integer, pass the JSON parse step, but break your database insert silently. Type validation with Zod, Joi, or JSON Schema is a non-negotiable safety layer.
7

Quick Cheat Sheet — Every AI JSON Error and Its Fix

jsonBefore and after — all 8 AI JSON error patterns
// ❌ TYPICAL AI OUTPUT (invalid)
{
  // User profile object
  name: 'Alice',                        // unquoted key + single quote
  "age": 30,
  "active": True,                       // Python literal
  "score": NaN,                         // JS-only value
  "balance": undefined,                 // JS-only value
  "tags": ["admin", "editor",],         // trailing comma
  "timeout": 030,                       // leading zero
  "priority": +1,                       /* block comment */
}

// ✅ VALID JSON (all errors fixed)
{
  "name": "Alice",
  "age": 30,
  "active": true,
  "score": null,
  "balance": null,
  "tags": ["admin", "editor"],
  "timeout": 30,
  "priority": 1
}
1

Use our AI JSON Error Explainer

Paste your broken AI-generated JSON into unblockdevs.com/json-error-explainer. It detects all 8 error patterns simultaneously, explains each one in plain English with RFC spec references, and fixes all auto-fixable errors in one click.

2

Use JSON mode in your AI API calls

Enable response_format: { type: "json_object" } (OpenAI), tool_use with a schema (Anthropic), or responseMimeType: "application/json" (Gemini). Structured outputs eliminate trailing commas, single quotes, and most syntax errors at the model level.

3

Add a repair function to your pipeline

Use the repairAiJson() function from this guide as a preprocessing step before JSON.parse(). This handles the cases where JSON mode is unavailable or where older models are used.

4

Validate schema after parsing

Use Zod (TypeScript), Joi (JavaScript), Pydantic (Python), or jsonschema (Python) to validate the parsed object's shape and types. Syntactically valid JSON can still have the wrong data types or missing required fields.

5

Improve your prompt

Explicitly list the JSON rules in your system prompt. Provide a concrete example of the exact output shape. Ask the model to self-verify before responding. These prompt engineering steps reduce errors by 60–80% without requiring API features.

🔍 AI JSON Error Explainer

Paste broken AI-generated JSON and get instant plain-English explanations for every error — trailing commas, Python True/False/None, JS undefined/NaN, unquoted keys — with one-click auto-fix and RFC spec references. 100% browser-based, nothing uploaded.

Fix My AI JSON Now →

Frequently Asked Questions