Every JavaScript developer has seen it: JSON.parse() throws a SyntaxError and your application crashes. The JSON came from an API, a config file, or a user's clipboard — and it just won't parse. In this guide we'll walk through exactly why that happens, what broken JSON looks like in the wild, and how to handle it gracefully — from a simple try/catch to automatic repair.
1. Why JSON.parse() Fails
The JSON standard (RFC 8259) is deliberately strict. JSON.parse() implements it exactly — any deviation, no matter how minor, throws a SyntaxError with no partial recovery:
try {
const data = JSON.parse('{ name: "Ada" }'); // unquoted key
} catch (err) {
console.error(err.message);
// SyntaxError: Expected property name or '}' in JSON at position 2
}Unlike a browser parsing HTML (which has an error-recovery model baked in), the JSON parser is a hard gate. Strict parsing is a feature: it forces producers to emit clean data. But when you don't control the data source — LLM output, hand-edited config files, third-party APIs — you need a strategy for when that gate slams shut.
2. The Most Common Broken JSON Patterns
Before reaching for a repair library, it helps to recognize what you're dealing with. Almost all real-world broken JSON falls into one of these categories:
Single quotes instead of double quotes
// ❌ Invalid JSON
{ 'name': 'Ada Lovelace' }
// ✅ Valid
{ "name": "Ada Lovelace" }JavaScript object literals accept single quotes; JSON does not. Developers copy an object literal directly into a JSON context and hit this error constantly.
Trailing commas
// ❌ Invalid JSON
{
"name": "Ada",
"active": true, // trailing comma
}
// ✅ Valid
{
"name": "Ada",
"active": true
}Modern JavaScript allows trailing commas in arrays and objects. JSON does not. This is the single most common error in hand-edited JSON files.
Unquoted object keys
// ❌ Invalid JSON
{ name: "Ada", score: 98 }
// ✅ Valid
{ "name": "Ada", "score": 98 }JavaScript object literals don't require quoted keys. JSON requires all keys to be double-quoted strings, no exceptions.
JavaScript comments
// ❌ Invalid JSON
{
// this is the user record
"name": "Ada",
/* added 2024 */
"active": true
}JSON has no comment syntax. Comments are sometimes added to config files (JSONC — JSON-with-Comments — is a popular extension), but JSON.parse() will reject them.
Multi-line strings
// ❌ Invalid JSON
{
"description": "line one
line two"
}
// ✅ Valid — escape the newline
{
"description": "line one\nline two"
}String values in JSON must be on a single line. Literal newlines inside a string are not allowed; use the \n escape sequence instead.
NaN, Infinity, and undefined
// ❌ Not valid JSON
{ "ratio": NaN, "limit": Infinity, "value": undefined }
// ✅ Valid alternatives
{ "ratio": null, "limit": 1e308, "value": null } These are valid JavaScript values but not part of the JSON specification. JSON.stringify() silently converts them (NaN and Infinity become null; undefined properties are dropped entirely), which can cause subtle round-trip bugs.
Python literals
// ❌ Python-style — invalid JSON
{ "active": True, "deleted": False, "value": None }
// ✅ Valid JSON
{ "active": true, "deleted": false, "value": null } JSON was designed to interoperate with multiple languages. Python's capitalized True, False, and None are a frequent source of cross-language data bugs.
3. "Repair" and "Parse" Are Not the Same Thing
It's important to distinguish between two fundamentally different operations:
- Strict parsing — validate that the input is exactly correct JSON, report the precise location of any error, reject anything that deviates. Use this when you control the data producer and want to enforce a contract.
- Repair parsing — attempt to recover a valid JSON value from a syntactically imperfect input using a set of heuristic rules. Use this when the data comes from an untrusted or imprecise source (LLM output, user clipboard, legacy service).
A repair parser makes assumptions. If it encounters True it assumes you meant true. If it encounters a trailing comma it removes it. These assumptions are almost always correct for the patterns listed above — but they can silently mask a genuinely malformed document where the "fix" changes the intended meaning.
The right tool depends on the context. In a schema-validated API response pipeline, you want strict parsing so bad data surfaces immediately. In a developer tool where a human is pasting JSON they copied from a Slack message, repair parsing saves time.
Libraries Worth Knowing
Two npm packages do most of the heavy lifting, with complementary trade-offs:
jsonrepair— a tolerant repair parser. Hands it bad JSON and you get a best-effort valid string back. It handles the patterns above (single quotes, trailing commas, unquoted keys, comments, Python literals, markdown fences, unclosed brackets, partial input). Synchronous, zero dependencies, tiny — ideal when you have a full document in memory.clarinet— a SAX-style streaming JSON parser. Use it when the JSON arrives in chunks (a stream, a large file, an LLM response token-by-token) and you need to react as keys/values appear rather than wait for the full document. It is strict about syntax, so pair it withjsonrepairif the source is unreliable.
Rule of thumb: repair when you have a small, unreliable blob; stream when the document is large or arrives progressively.
4. Catching Errors and Giving Users Friendly Feedback
The minimum viable pattern is a try/catch. Always do this — never let JSON.parse() throw uncaught:
function safeParseJson(text) {
try {
return { ok: true, value: JSON.parse(text) };
} catch (err) {
return { ok: false, error: err.message };
}
}
const result = safeParseJson(userInput);
if (!result.ok) {
showError(`Could not parse JSON: ${result.error}`);
} The error message from JSON.parse() varies by JavaScript engine. V8 (Node.js, Chrome) includes a position hint:
// V8 error message
"Expected ',' or '}' after property value in JSON at position 42"
// Firefox SpiderMonkey
"JSON.parse: expected ',' or '}' after property value in object
at line 3 column 5 of the JSON data"The position information is useful but engine-specific. If you need reliable line/column reporting across environments, a custom recursive-descent parser can emit structured errors that are much easier to display to users.
5. When to Auto-Repair vs. Ask for Confirmation
Not all repairs carry the same risk. Here's a practical heuristic:
- Safe to repair automatically — trailing commas, whitespace normalization, quote style conversion, unquoted keys, JavaScript comments, Python boolean/null literals. These are mechanical transformations with no semantic ambiguity.
- Consider prompting the user — structural repairs like auto-closing an unclosed object or array (
{"name": "Ada"→{"name": "Ada"}), or stripping content (removing a comment that looks intentional). The repair is probably right, but the user might want to verify. - Always flag, never silently fix — type coercions like
NaN → nullchange the data value. Show the user what changed.
A good repair UI shows a diff: the original input on the left, the repaired output on the right. The user can confirm the fix is correct before copying or submitting the result.
6. The Privacy Advantage of In-Browser JSON Processing
When you process JSON locally in the browser — using the JavaScript engine that's already running the page — the data never leaves the user's machine. This matters more than developers often realise:
- API keys and credentials — developers regularly paste JSON payloads that contain secrets. A server-side tool logs every request.
- PII and health data — GDPR and HIPAA compliance becomes much simpler when there is no data transfer.
- Corporate data — many security policies prohibit pasting internal data into third-party web services.
In-browser processing gives you zero-risk JSON repair: no server, no logs, no data retention. The computation happens in a <textarea> and a few kilobytes of JavaScript.
Frequently Asked Questions
How do I handle a JSON.parse error in JavaScript?
Wrap the call in try/catch and return a structured result instead of letting the SyntaxError propagate (see the safeParseJson helper above). Never call JSON.parse() on untrusted input without a guard.
Is there a way to parse broken JSON automatically?
Yes — a repair parser recovers a valid value from imperfect input by applying heuristics (removing trailing commas, converting single quotes, lowercasing True). Use it for untrusted sources like LLM output or pasted text, not for contract-validated API responses where you want bad data to surface.
When should I repair JSON vs. reject it?
Repair when a human pasted approximate JSON or an LLM produced it; reject (strict-parse) when you control the producer and want to enforce a schema. Type coercions like NaN → null should always be flagged, never silently applied.
What's the most common cause of broken JSON?
Treating a JavaScript object literal as JSON — single quotes, unquoted keys, and trailing commas. See JSON vs JavaScript objects and the syntax-error reference at [object Object] and other errors.
7. Try It Now — Paste Your Broken JSON
If you have a malformed JSON string you need to fix right now, JSON Fix handles all the patterns above — single quotes, trailing commas, unquoted keys, Python literals, comments, markdown code fences, and more. Everything runs in your browser; nothing is sent to a server.
- JSON Fix — paste broken JSON, get clean JSON back instantly
- Fix JSON Online — how online JSON fixers work and when to use them
- Repair LLM JSON Output — targeted guide for fixing AI-generated JSON
- JSON Formatter vs JSON Repair — when to use each tool
- JSON Diff — compare two JSON documents side by side to see exactly what changed