10 Most Common JSON Errors and How to Fix Them (2026)
I keep a list in my head of the JSON errors that have actually wasted my time over the years, and the same eight or nine keep coming up. The good news is that almost none of them are deep — once you've seen each pattern, you spot it in two seconds. Here are the ones I run into most, in roughly the order of how often they bite, with what each one looks like and what to do about it.
1. Trailing commas
{
"name": "Ada",
"skills": ["math", "computing",],
}
JavaScript, Python and most other modern languages allow trailing commas. JSON does not. Both the comma after "computing" and the comma after the closing array are illegal.
Fix: Remove every comma that immediately precedes a closing } or ].
Why it exists: JSON's spec predates the languages that adopted trailing commas, and Crockford has stated he prefers the stricter form. If you need trailing commas, you have JSON5 or JSONC — both require a non-standard parser.
2. Single quotes
{'name': 'Ada'}
JSON requires double quotes for both keys and string values. This is the most common error when pasting from a JavaScript REPL, a Python dictionary, or anywhere else that allows single-quoted strings.
Fix: Replace every ' with ". If a string contains an apostrophe — it's — escape it as \' only when inside single-quoted source code; in JSON, "it's" (with double quotes wrapping a string containing an apostrophe) is fine and needs no escaping.
3. Unquoted keys
{name: "Ada", age: 200}
A JavaScript object literal allows unquoted keys. JSON does not. Every key must be a quoted string.
Fix: Wrap every key in double quotes. {"name": "Ada", "age": 200}.
4. Comments
{
// primary user
"name": "Ada"
}
JSON does not support comments — not //, not /* */, not #. This is one of the most-debated design decisions of the format, but it has not changed in over twenty years and is unlikely to.
Fix: Strip the comments before parsing. If your file is meant to be hand-edited and needs explanations, switch to JSONC (JSON with Comments, used by VS Code), JSON5, YAML or TOML.
If you only need to leave a note inside a JSON file that's read by a tool you don't control, a common trick is to add a sibling field:
{
"_comment": "primary user record, do not delete",
"name": "Ada"
}
It's ugly but it parses.
5. Unescaped control characters in strings
{
"bio": "Wrote the first
algorithm intended for a machine."
}
A literal newline (or tab, or any character with codepoint < 32) inside a string value is illegal. JSON strings must be on one logical line; line breaks must be encoded as \n.
Fix: Escape the offending character:
{ "bio": "Wrote the first\nalgorithm intended for a machine." }
If you're constructing JSON from source data that may contain control characters, use your language's JSON.stringify (JavaScript), json.dumps (Python) or equivalent — they handle escaping automatically.
6. Mismatched or missing brackets
{
"items": [1, 2, 3
}
A missing or mismatched }/] is a syntax error. JSONNeat and similar validators report the location where the parser noticed something was wrong — often a few characters or lines *after* the actual mistake, because the parser only knows things have gone wrong when it sees an unexpected token.
Fix: Use a JSON validator that points to line and column. Read backwards from the reported position to find the missing bracket.
Prevention: Always edit JSON in a tool with bracket-matching (VS Code, Sublime, JetBrains IDEs, vim with plugins).
7. Invalid Unicode escapes
"price: \u00A3" // valid: £
"oops: \u00" // invalid: only two hex digits
"oops: \uGGGG" // invalid: G is not a hex digit
A \u Unicode escape must be followed by exactly four hexadecimal digits. Three, five, or any non-hex character will fail.
Fix: Ensure four hex digits after every \u. For characters outside the Basic Multilingual Plane (most emoji, some CJK extension characters), use a surrogate pair: \uD83D\uDE00 for 😀.
8. Numbers with leading zeros
{"code": 007}
JSON numbers cannot have leading zeros, except for the number 0 itself. 007 is a syntax error.
Fix: If the leading zero is significant — phone numbers, product codes, ZIP codes — store it as a string: "007". JSON numbers are meant for arithmetic; leading zeros imply they're really identifiers, not quantities.
9. NaN and Infinity
{"temperature": NaN}
JSON allows only finite decimal numbers. NaN, Infinity and -Infinity are legal JavaScript values but not legal JSON.
Fix: Decide what these values *mean* in your context and serialize accordingly:
- For "no value" or "missing", use
null. - For "out of range" or "error", use a string like
"NaN"or an explicit error structure. - For positive/negative overflow, use a very large finite number or a string.
If you're using JavaScript and JSON.stringify is producing these errors, write a replacer:
JSON.stringify(obj, (key, value) => {
if (typeof value === 'number' && !isFinite(value)) return null
return value
})
10. BOM and invisible characters
A UTF-8 byte-order mark (BOM, \uFEFF) at the start of a JSON file is invisible in most editors but illegal at the start of the document. Some parsers tolerate it; many don't.
[invisible BOM]{"name": "Ada"}
Fix: Save the file without a BOM. Most editors have a setting like "Save without BOM" or "Encoding: UTF-8 (no BOM)". On the command line:
sed -i '1s/^\xef\xbb\xbf//' file.json
Related hazards in this category:
- Non-breaking spaces (U+00A0) disguised as regular spaces. They look identical but are not valid JSON whitespace.
- Zero-width characters (U+200B, U+200C, U+200D) pasted from Slack, browsers, or some chat apps. They appear nowhere on screen but break parsing.
- Smart quotes (U+201C, U+201D) replacing regular quotes after a copy-paste through a word processor.
When all else fails and the file *looks* fine, run it through cat -A file.json (Linux/macOS) or paste it into a hex editor — invisible characters become visible.
Bonus: HTML returned instead of JSON
This isn't a JSON syntax error, but it produces one. When a server returns an HTML error page (a 500, a 502, a login redirect) and the client calls JSON.parse on the body, you get:
Unexpected token < in JSON at position 0
The < is the start of <!DOCTYPE html>.
Fix: Check the HTTP status code and Content-Type before parsing. fetch makes this easy:
const response = await fetch('/api/users')
if (!response.ok) throw new Error(`HTTP ${response.status}`)
const data = await response.json()
How I debug a stubborn one
If the error message and the line/column don't get me there in the first thirty seconds, I bisect: delete the bottom half of the document and re-validate. If the error stays, the problem is in the top half. If it goes away, it's in the bottom half. Repeat. It takes five rounds to narrow a thousand-line document down to the offending line. I'd rather do that than read every comma and bracket.
The trick I use most often, though, is to look at the character *just before* the reported position. Parsers report where they got confused, not where you went wrong, and the cause is usually a few characters back. Missing comma between two object properties? The parser only realises something is off when it hits the next key, so it points at the key, not the comma.
If you've read this far and you still can't figure it out, paste the document into the validator and email me what it says at [email protected]. I've seen most of these and I'm happy to look.
Related tools: JSON formatter, validator, minifier.