JSON Repair / Fixer
Turn almost-JSON into valid JSON with a logged, visible fix for every change — entirely on this device.
True/False become true/false; None, NaN and Infinity become null — flagged, because that changes meaning. Closes brackets a cut-off stream left open — flagged, because data may be missing. Wraps line-separated or concatenated JSON documents into one array. Pulls the first balanced {…} or […] out of surrounding text before repairing.
The repaired document appears here as you type — with every change listed below it.
One log entry per fix — nothing is changed silently.
Press ? for shortcuts
Do it offline:$ npx jsonrepair broken.json > fixed.json
How to use it
- Paste the broken text or drop a .json file up to 10 MB — small inputs repair as you type, very large ones wait for a button that names their size.
- Read the change log beside the repaired output; every entry states its line, and a jump button lands on the exact spot in the result.
- Check entries chipped “changes meaning” — closing a truncated stream or mapping None to null is an informed guess about absent data, so verify those against the source.
- Untick a fix class you would rather handle yourself: when the input needs one that is off, the page refuses and names the class.
Almost-JSON is everywhere: a model reply that stops mid-object, a Python dict pasted where JSON was expected, a config full of comments, an export riddled with smart quotes. This page turns that text into strict JSON and shows its work — a numbered log names every fix with the line it touched, and any repair that could alter data carries a visible warning instead of a quiet guess.
Examples
{name: 'Ana', age: 31,}{
"name": "Ana",
"age": 31
}Classic LLM-and-Python shape, four fixes logged: both bare keys get quotes, the single-quoted value is rewritten, the trailing comma goes. None of them alters the parsed data, so no entry carries a warning.
{"items": [{"id": 1}, {"id": 2{
"items": [
{
"id": 1
},
{
"id": 2
}
]
}A stream cut off mid-array: three unclosed brackets are closed in one flagged entry, because inventing the ending of truncated data changes meaning — whatever followed "id": 2 is gone.
{"a": None, "b": NaN}{
"a": null,
"b": null
}Python literals in JSON clothing: None and NaN become null, and both entries are flagged — null is the nearest JSON value, not the same value, since RFC 8259 has no token for NaN at all.
{"id": 1, "ok": true}
{"id": 2, "ok": false}[
{
"id": 1,
"ok": true
},
{
"id": 2,
"ok": false
}
]Two NDJSON lines become one array with a single logged wrap; each line keeps its exact parsed value. Turn the ndjson class off to have per-line documents refused instead.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Valid input is left completely alone
If the text already parses, the page says there is nothing to repair, offers formatting, and logs zero changes — an empty change log is the proof, not a decoration.
Concatenated documents become one array
Paste {…}{…} with no separator between the objects and the result is a two-element array, with the wrap recorded as its own log entry. The same rule covers newline-delimited exports.
Smart quotes and odd whitespace are normalized
Text that traveled through a word processor arrives with “curly” quotes and non-breaking spaces. Both are rewritten to plain JSON punctuation, each on its own logged line — the non-standard character is named by code point.
A comment containing */ can defeat repair
Line comments are stripped wherever they sit, */ included. A block comment with */ in its text ends early by definition, and the leftover tail usually cannot be reconciled — the page then refuses honestly rather than shipping a wrong guess.
Cosmetic and semantic fixes are kept apart
Requoting a key, removing a comma or dropping a comment never touches the parsed value. Closing truncated brackets, completing a missing value or mapping None and NaN to null can — exactly those entries wear the warning chip.
Why the ceiling sits at 10 MB
Past that size the typical input is a file truncated by whatever produced it, better handled outside a browser tab. The refusal prints the exact limit and names the same repair library as a command line.
Common errors
Input is larger than the 10 MB limit for this tool. For files this big use the CLI: npx jsonrepair broken.json > fixed.json- A refusal, never a truncation — repairing half a file would quietly produce a wrong document. The named command runs the identical repair engine on files of any size.
This looks like binary data (NUL byte at offset 8) — JSON repair works on text.- A NUL byte in the first 8 KB marks the input as a compiled or compressed file — typically a file pasted by handle rather than by content. Open it as text and paste what it says.
Could not produce valid JSON — colon expected at byte 26.- The honest-failure state: the byte position marks where reconciliation broke down, and when a valid prefix can still be recovered the page shows it, labeled, so partial data stays usable.
This input needs the `quotes` fix class, which is turned off — nothing was repaired.- Not a defect in your data — a boundary you set. The page never applies half of the needed fixes; re-enable the named class with one click, or make that edit yourself.
FAQ
Why does JSON from an LLM so often fail to parse?
Two mechanical reasons dominate. Generation stops when a length limit is reached, cutting the document mid-token and leaving brackets open; and model output frequently borrows Python and JavaScript habits — single quotes, True and None, trailing commas, a Markdown fence around the payload. Each is a specific, machine-fixable pattern with its own fix class here.
Can the repaired document mean something different?
Yes, and the page is built around admitting it. Quote, comma and comment fixes leave the parsed value identical. Closing a truncated stream or replacing None with null repairs the form without recovering the content — the log flags every such entry, and only the file's producer knows what was lost.
What happens to the broken JSON I paste here?
It is repaired on this device and sent nowhere — no request carries your text, and a link is minted only when you press Share. Your last input is kept locally so a reload does not eat it, and even that is skipped when the content looks credential-shaped.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Run the repair again, at any input size.
- ⌘/Ctrl + S
- Download the repaired JSON as a .json file.
- ⌘/Ctrl + C
- Copy the repaired JSON when no text is selected.
- ⌘/Ctrl + Shift + C
- Copy the repaired JSON even while a selection exists.
- t
- Switch the color theme.
- ? or ⌘/Ctrl + /
- Open the shortcut help overlay.
- Esc
- Close the topmost overlay — the input always stays.