JSON Fixer — Repair Broken JSON
Paste JSON that refuses to parse and get a corrected, standards-compliant document back
Input
Repaired JSON
What the JSON Fixer does
You copied a payload out of a log viewer, a chat thread or a colleague's screenshot, pasted it into your code, and everything blew up with Unexpected token } in JSON at position 214. The data is fine. The syntax is not. That gap — readable to you, unreadable to a parser — is what this page closes.
Paste the broken document on the left, press Fix JSON, and the corrected version appears on the right. Keys get their double quotes, single-quoted strings are re-quoted, trailing commas disappear, unbalanced brackets are closed, and Python-flavoured True/False/None become true/false/null. What comes back is plain JSON as defined by RFC 8259 — the version every JSON.parse, json.loads and Jackson on earth agrees on.
One thing worth knowing up front: a repair is a guess about intent. If a bracket is missing, there is usually exactly one sensible place it belongs, and that is the place it goes. But the result is a suggestion, not a verdict — read the right-hand panel before you paste it into production. If you only want to know whether a document is valid and where it fails, the JSON Validator gives you the position and the message without changing a byte.
How to repair a broken JSON file
- Paste the broken document – Drop the failing JSON into the left panel. Use Upload if it lives in a .json or .txt file, or Sample to load a deliberately mangled telecom record you can experiment with.
- Press Fix JSON – The button sits at the top of the input panel. It stays disabled while a repair is in flight so you cannot fire two requests at the same document.
- Read the right-hand panel – The corrected document appears on the right with syntax highlighting. Skim it before you trust it — check that no key was dropped and that string values still read the way you expect.
- Compare the numbers – Long identifiers such as an ICCID or an IMSI are the values most often damaged by careless tooling. Check that a 19-digit number came back with all 19 digits intact and no trailing zeros.
- Copy, minify or download – Copy puts the corrected JSON on your clipboard, Minify strips it back to one line, and Download saves it as fixed.json.
Pro tip: if the repair comes back looking wrong, the usual cause is a truncated paste — a document cut off mid-string has no single correct completion. Grab the whole payload from the source and try again.
Example: a subscriber record that will not parse
This is the shape of thing that lands in a bug report — hand-edited, half Python, half JSON, with a comma where a closing brace should be. On the left is what was pasted; on the right is what comes back.
{
subscriberId: 'SUB-100418',
msisdn: "+441632960421",
iccid: 8901240544102066246,
roaming: True,
tags: ["priority", "corporate",],
}{
"subscriberId": "SUB-100418",
"msisdn": "+441632960421",
"iccid": 8901240544102066246,
"roaming": true,
"tags": ["priority", "corporate"]
}Seven ways JSON breaks, and what is actually wrong
Every one of these produces a parse error that names a position rather than a cause, which is why they cost so much time. Here is what the parser is really objecting to in each case.
A trailing comma
{"msisdn": "+441632960421", "plan": "5G",}JavaScript object literals have allowed a dangling comma since ES5, so your editor does not flag it and your eye slides straight past. JSON never allowed one. The grammar in section 4 of RFC 8259 requires a member after every comma, so the parser reaches } while it is still waiting for a key. This is far and away the most common breakage we see.
Single quotes instead of double
{'imsi': '234159876543210'}Printing a dict in a Python REPL, or an object in some JS consoles, gives you single quotes. It looks like JSON and it is not: JSON strings are double-quoted, full stop. The parser sees ' where a string or a } should start and stops on the very first character of the key.
Unquoted keys
{subscriberId: "SUB-100418", apn: "internet"}This is valid JavaScript and valid JSON5, so it survives a code review and then dies at runtime. In JSON, a member name must be a quoted string — see the object production on json.org, which is the one-page railroad diagram worth bookmarking.
A missing closing brace
{"cell": {"lac": 4021, "tac": 17}←Almost always a copy that stopped at the edge of a terminal window or a log line truncated at a byte limit. JSON.parse reports it as Unexpected end of JSON input, which tells you nothing about where the document actually went wrong — the error is at the end, the mistake was wherever the copy stopped. MDN's JSON.parse reference lists the exact wording each engine uses.
Python True, False and None
{"roaming": True, "apn": None}Python capitalises its booleans and calls null None; JSON uses lowercase true, false and null. The json module docs spell out that translation table, which is exactly why str(my_dict) is not a serializer and json.dumps is. Anyone who has debugged a payload built with an f-string has met this one.
An invisible BOM at the start
<U+FEFF>{"iccid": "8901240544102066246"}
A byte order mark is a zero-width character some Windows editors prepend when saving UTF-8. You cannot see it, your diff tool may not show it, and the file looks perfect — but the parser sees a character before { and refuses at position 0. The Unicode BOM FAQ explains why it exists; for JSON, RFC 8259 says implementations must not emit one.
Comments
{
// temporary override
"qci": 9
}Douglas Crockford removed comments from JSON deliberately, because people were using them to smuggle parsing directives. Config formats that accept them — tsconfig.json, VS Code settings — are JSONC, a superset, not JSON. If you need annotations in a document that has to stay portable, put them in a real key such as "_comment" and let them travel with the data.
If you are staring at a message you have never seen before, the JSON tag on Stack Overflow has a decade of answers about parser wording that differs between Node, Python, Java and Go for the same broken byte.
When you will reach for this
A payload pasted out of a log or a ticket
Application logs escape, truncate and re-wrap JSON on its way to disk, and by the time it reaches a bug report it has usually been through a chat client as well. Rather than hand-editing quotes back in at eleven at night, paste it here, get a parseable document, then send it through the JSON Tree Viewer to find the field you actually care about.
Hand-edited configuration that stopped loading
Someone adds a service to a config file, leaves a comma after the last entry, and the whole deployment refuses to start with an error pointing at the closing brace. Repair it here, then run the result through the JSON Formatter so the indentation matches the rest of the file and the diff stays small.
Output from a script that built JSON with string concatenation
Assembling JSON by hand with f-strings or template literals works right up until a value contains a quote, a newline or a None. The fixer will get you a valid document to keep moving, but treat it as a signal: the real fix is a serializer, not a string. Once it parses, JSON to Table is the fastest way to eyeball a few thousand rows for the fields the script got wrong.
Data with very long identifiers
Telecom and finance payloads are full of 18- and 19-digit numbers — ICCIDs, IMSIs, card numbers, snowflake IDs. Plenty of tools quietly round those past 9007199254740991 because they route everything through a double. This page hands the repaired text straight to the editor without re-serializing it, so the digits you paste in are the digits you get back.
Frequently asked questions
What kinds of problems can it actually fix?
Syntax problems: missing or wrong quote characters, unquoted keys, trailing and doubled commas, unbalanced brackets and braces, Python-style True/False/None, comments, and a stray BOM or control character at the start of the file. What it cannot do is invent data — if a value was truncated away, nothing can tell you what it said.
Will it change my data as well as my syntax?
It should not, and that is the thing to check in the output panel. Keys, string contents and numbers are meant to come through untouched; only the punctuation around them changes. A long integer such as an ICCID is a good canary — if all 19 digits survived, nothing has been re-serialized behind your back.
Why does my 19-digit ID sometimes come back wrong in other tools?
Because JavaScript numbers are IEEE-754 doubles and hold about 15 to 16 reliable digits. Any tool that parses your text into JS numbers and then prints them again will silently turn 8901240544102066246 into 8901240544102066000. This page shows you the repaired text as text rather than re-parsing and re-printing it, which is why the digits stay put.
Is there a size limit?
There is no hard limit in the page, but a repair on a multi-megabyte document is slow and the result is harder to review than it is worth. If you have a very large file, it is usually faster to find the one broken record — the validator reports a line and column — and repair that fragment on its own.
The output is not what I expected. What now?
Check the input for a paste that stopped early, or for two separate JSON documents concatenated with nothing between them. Both have more than one plausible repair. Splitting them and fixing each piece on its own almost always gives a cleaner result than repairing the whole mess at once.
Can I fix JSON with a trailing comma without any tool?
In Node you can use JSON5.parse or a lenient parser and re-serialize with JSON.stringify, which drops the comma as a side effect. In Python, ast.literal_eval handles single quotes and True/None but not comments. Both approaches work for one-off scripts; this page exists for the case where you just want the corrected text in front of you.
Does this replace validating my JSON?
No — it is the step after. Validate first to see what is wrong and where, repair if the problem is syntax, then format the result so it is readable. The JSON Validator, this page and the JSON Formatter are meant to be used in that order.