Common JSON Errors and How to Fix Them Fast
The eight JSON syntax errors that account for nearly every parse failure, what the error messages actually mean, and how to locate the problem quickly.
Table of contents
- 1. Trailing comma
- 2. Single quotes
- 3. Unquoted keys
- 4. Comments
- 5. Unescaped characters inside strings
- 6. Python or JavaScript literals
- 7. Empty response parsed as JSON
- 8. HTML where you expected JSON
- Reading the position number
- Errors that are not syntax errors
- Frequently asked questions
- Why does my JSON work in Python but not JavaScript?
- Can I make JSON.parse accept trailing commas?
- What is the maximum size JSON.parse can handle?
- Why does my JSON have a BOM?
- Related reading
- References
Almost every JSON parse failure is one of eight mistakes. Here they are, with the error message each one produces.
1. Trailing comma#
{ "a": 1, "b": 2 }The most common by far, because JavaScript, Python and most linters allow it. JSON does not.
Message: Unexpected token } in JSON at position 17
2. Single quotes#
{ "name": "Ada" }JSON requires double quotes for both keys and string values.
Message: Unexpected token ' in JSON at position 2
3. Unquoted keys#
{ "name": "Ada" }Valid JavaScript, invalid JSON.
Message: Unexpected token n in JSON at position 2
4. Comments#
{
// the user's name
"name": "Ada"
}JSON has no comments. If you need them, you are using JSONC or JSON5 — and your parser must know that.
Message: Unexpected token / in JSON at position 4
5. Unescaped characters inside strings#
{ "path": "C:\Users\ada" }
{ "quote": "she said "hello"" }
{ "text": "line one
line two" }Backslashes, double quotes and literal newlines all need escaping: \\, \", \n.
Message: Bad escaped character or Unterminated string
6. Python or JavaScript literals#
{ "ok": True, "value": None, "score": NaN }JSON has true, false and null — lowercase — and no NaN or Infinity at all.
Message: Unexpected token T in JSON at position 8
7. Empty response parsed as JSON#
const data = await response.json(); // throws on an empty bodyMessage: Unexpected end of JSON input
This one usually means the request failed and returned nothing, or returned a 204. Check the status before parsing:
if (response.status === 204) return null;
if (!response.ok) throw new Error(`HTTP ${response.status}`);8. HTML where you expected JSON#
Message: Unexpected token < in JSON at position 0
The < is the start of <!DOCTYPE html>. Your request hit an error page, a login redirect or a 404 handler rather than the API. This is not a JSON problem at all — log the raw response text and you will see immediately.
const text = await response.text();
try {
return JSON.parse(text);
} catch {
throw new Error(`Expected JSON, got: ${text.slice(0, 120)}`);
}That pattern turns an opaque parse error into an actionable one, and it is worth having in every API client.
Reading the position number#
Most engines report a character offset. Converting it to a line and column is the fast way to find the problem:
function locate(source, position) {
const before = source.slice(0, position);
return {
line: before.split('\n').length,
column: position - before.lastIndexOf('\n'),
};
}Newer V8 versions report line N column M directly. Firefox and Safari word their messages differently, which is why a tool that normalises both is useful.
Errors that are not syntax errors#
Two failure modes that look like JSON problems and are not:
Precision loss. {"id": 9007199254740993} parses fine and gives you 9007199254740992. No error, wrong data. Large integers must be strings.
Duplicate keys. {"a": 1, "a": 2} parses to {a: 2} with no warning. Every mainstream parser takes the last occurrence.
Frequently asked questions#
Why does my JSON work in Python but not JavaScript?#
Python's json module is stricter than people expect but ast.literal_eval is not — if you have been using the latter, you have been parsing Python literals, not JSON.
Can I make JSON.parse accept trailing commas?#
No, and you should not want to. Fix the producer, or use a JSON5 parser explicitly so the looseness is a deliberate choice.
What is the maximum size JSON.parse can handle?#
Bounded by memory rather than the spec. In a browser, parsing beyond ~100 MB will typically fail or freeze the tab. Stream it instead.
Why does my JSON have a BOM?#
Something saved it as UTF-8-with-BOM — often Windows Notepad or Excel. The BOM is an invisible character before the {, and it produces a position-0 error. Save as plain UTF-8.