A JSON fixer for almost-JSON
A lot of text that looks like JSON is not quite JSON: a JavaScript object literal, a Python dictionary printed with print(), a response cut off by a log limit, or a config file with comments. This JSON fixer rewrites such input into strict JSON and then formats it, so you do not have to hunt for each problem one error message at a time.
Repairs are done by the open-source jsonrepair library, running in your browser.
Example
This snippet has five separate problems:
{
name: 'Northwind', // company
"tags": ["api", "saas",],
"active": True,
"owner": {"name": "Priya" "email": null}
}
After Repair JSON:
{
"name": "Northwind",
"tags": [
"api",
"saas"
],
"active": true,
"owner": {
"name": "Priya",
"email": null
}
}
What gets fixed
| Problem | Before | After |
|---|---|---|
| Unquoted or single-quoted keys and strings | {name: 'Ana'} | {"name": "Ana"} |
| Trailing and missing commas | [1 2 3,] | [1, 2, 3] |
| Line and block comments | {"a":1,/* c */"b":2} | {"a": 1, "b": 2} |
| Python constants | None, True, False | null, true, false |
| Truncated document | {"a":1,"b":[1,2 | {"a": 1, "b": [1, 2]} |
| Missing colon or value | {"a" 1, "b":} | {"a": 1, "b": null} |
| Unescaped quotes inside a string | "he said "hi"" | "he said \"hi\"" |
| Curly quotes from word processors | “curly” | "curly" |
It also strips wrappers that often surround JSON: Markdown code fences (```json), a JSONP callback such as callback({...});, and MongoDB-style ObjectId("...") calls, which become plain strings. Several objects on separate lines are combined into one array, and a stray extra closing bracket at the end is dropped.
Review guessed values
Some inputs have more than one reasonable fix, and the repair picks one. A few worth knowing:
NaNand hexadecimal numbers such as0x1Fbecome strings ("NaN","0x1F"), andundefinedbecomesnull.- Two commas in a row inside an array can change the structure:
[1,,2]comes out as[[1], 2]. Fix such spots by hand. - Plain text with no JSON structure at all is turned into a single JSON string rather than rejected.
- A truncated string is closed where the input ends, so the last value may be incomplete.
When repair fails
If the damage is ambiguous, the tool stops with "Could not repair JSON" and the position, for example Object key expected at position 7 (line 1, column 8) for {"a":1,,"b":2}. Text after the end of a complete document, like {"a":1} garbage, is also reported. Remove the offending characters at that position and repair again.
If the input was already valid, you see "JSON was already valid — formatted it." and nothing but whitespace changes.
Fixer or formatter?
Use the JSON validator when you want to know what is wrong, for instance to fix the program that produced the data. Use this fixer when you just need usable JSON now. If the file is meant to keep comments and trailing commas, it is probably JSON5; the JSON5 formatter keeps it in that format. To strip the empty fields out of the repaired result, continue with the JSON cleaner.
Privacy
Repair runs in your browser, and the pasted text is not uploaded. Load URL and Save & Share are the only features that use our server.
JSON fixer in Python
The json module reports errors but never repairs them, so a general fixer needs the third-party json-repair package: repair_json() takes the broken text and returns valid JSON, coping with unquoted keys, single quotes, trailing commas, comments, missing commas and unclosed brackets. The shortcut people try first, text.replace("'", '"'), breaks as soon as a value contains an apostrophe, as in O'Neil. When the text is really a printed Python dictionary, ast.literal_eval() from the standard library reads it safely and json.dumps() writes it back as JSON.
# pip install json-repair
import ast
import json
from json_repair import repair_json
broken = """{name: 'Northwind Labs', "tags": ["api", "saas",], "active": True, // note
"owner": {"name": "Priya" "email": "priya@example.com"}"""
fixed = repair_json(broken) # returns valid JSON text
data = json.loads(fixed)
print(json.dumps(data, indent=2))
# A printed Python dict needs no package: literal_eval reads it safely
printed = "{'id': 7, 'name': \"O'Neil\", 'active': True, 'manager': None}"
print(json.dumps(ast.literal_eval(printed)))
# {"id": 7, "name": "O'Neil", "active": true, "manager": null}
A repair is always a guess, so paste the same text above and compare the two results before relying on either.