>_toolkitbox

~/tools / LLM JSON Repair

LLM JSON Repair — Fix the broken JSON an AI model returned

Fix the almost-JSON that AI models return: it strips code fences and chatter, removes trailing commas and comments, fixes quotes, keys and Python values, and lists exactly what it changed. Nothing leaves your browser.

Indent

Only fixes with one clear answer are applied. Anything else is reported with its position instead of being guessed.

Everything runs in your browser. The text you paste is not uploaded.

Language models often wrap JSON in a code fence and a sentence, then break the syntax: a trailing comma, single quotes, a comment, True instead of true. JSON.parse rejects all of these. This tool finds the JSON in the text and repairs only the problems that have one clear fix, then lists every change so you can judge it. If the output was cut off, it closes what is open and warns you that data may be missing. It does not guess: input it cannot repair is reported with a position instead of being silently altered.

Use Cases

  • Fixing a model's reply before it goes into JSON.parse or a config file
  • Cleaning a reply that has a code fence and an explanation around the JSON
  • Checking what changed, so a repaired value does not slip into production unnoticed

Usage

  1. Paste the model's reply, or load the example.
  2. Read the repaired JSON and the list of changes under it.
  3. Copy the result. Changes marked in amber can lose information, so check them.

What counts as valid JSON

  • Strings and member names use double quotation marks only. Single quotes are not part of the grammar.
  • There are no comments. The only filler allowed is whitespace.
  • A comma goes between members or elements only, so a trailing comma is not allowed.
  • A value is an object, array, number or string, or one of false, null and true. Infinity, NaN and undefined are not JSON values.
  • Numbers cannot have a leading zero or a leading +, and a decimal point needs digits on both sides, so 012, +5, .5 and 5. are all invalid.
  • Control characters U+0000 to U+001F inside a string must be escaped, so a raw line break in a string is invalid.
  • The top level can be any value, not only an object or an array.

How model output usually breaks

ProblemExampleWhat this tool does
Code fence and chatterSure! ```json { … } ``` Hope this helpsTakes only the JSON
Trailing comma[1, 2,]Removes the comma
Comment{"a": 1 // note}Removes the comment
Single quotes{'a': 'b'}Uses double quotes
Bare key{a: 1}Puts quotes around the key
Python values{"ok": True, "x": None}Writes true and null
Raw line break in a string"line one⏎line two"Escapes it as \n
NaN or undefined{"x": NaN}Writes null and warns that the value is lost
Cut-off reply{"items": [{"id": 1}, {"id":Closes what is open and warns that data may be missing

What is safe to repair, and what is not

A repair is safe when the broken text has only one sensible reading. A trailing comma, a comment or a code fence can be removed without changing what the data says. Other changes alter the meaning, so they are marked and you should check them: closing a reply that was cut off gives valid JSON that is missing data, and turning NaN into null throws away the original value.

Two limits come from JSON itself. RFC 8259 says names within an object should be unique and that the behavior of software is unpredictable when they are not; this tool keeps the last one, as JSON.parse does. The RFC also says software interoperates well when it expects no more range or precision than an IEEE 754 double. This tool keeps numbers as you wrote them, but a program that parses a very long integer into a double rounds it. Integers between -(2^53)+1 and (2^53)-1 are exact.

Better: ask the API for structured output

Repairing is a fallback. The model APIs can constrain the output to a schema, and the three vendors document it differently.

  • OpenAI: Structured Outputs makes the model generate responses that adhere to your JSON Schema, while JSON mode only guarantees valid JSON. A refusal may not follow the schema, and a response that hits the maximum token limit is incomplete (status incomplete, reason max_output_tokens).
  • Anthropic: structured outputs use constrained decoding so the response follows your schema, and the documentation says this holds in most cases. A refusal (stop_reason refusal) or a reply cut off by max_tokens may not match the schema, so check stop_reason before parsing.
  • Google Gemini: the model is configured to produce JSON that adheres to the schema you give. Semantic correctness is not guaranteed, so validate the values, and some constraints such as minLength and maxLength are not enforced.

None of the three documents promises valid JSON when the output is cut off. Check why the model stopped before you trust a parsed result.

Sources (checked 2026-10-23): RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format / OpenAI: Structured Outputs / Anthropic: Structured outputs / Google AI for Developers: Structured output

FAQ

What does it fix?

It removes the code fence and the text around the JSON; removes trailing commas and // or /* */ comments; turns single quotes and curly quotes into double quotes; quotes bare keys; turns True, False and None into true, false and null; adds missing commas between lines; escapes raw line breaks inside strings; and rewrites numbers such as +5, .5 and 0x1F into valid JSON numbers.

What does it never change?

Values. Strings are kept character for character, and numbers keep their digits, so a long ID such as 12345678901234567890 is not rounded. Duplicate keys follow JSON.parse: the last one wins.

What if the reply was cut off?

It closes the open strings, arrays and objects and drops a key that has no value yet. That makes the text valid but not complete, so the result is marked as possibly missing data. Ask the model to continue, or raise its output limit, rather than trusting a truncated result.

Why did NaN or undefined turn into null?

JSON has no NaN, Infinity or undefined. The tool writes null in their place and marks it, because the original value is lost.

Why does it refuse some input?

When there is no single obvious fix, such as an ellipsis (...) standing in for omitted items, or a bare word where a value should be, it stops and shows where, instead of guessing.

Is the text sent to a server?

No. The repair runs in your browser.

Related