Why JSON Is So Strict About Syntax
If you've ever seen SyntaxError: Unexpected token < in JSON at position 0 or JSON.parse: unexpected character, you know how frustrating JSON errors can be. Unlike HTML or CSS, which browsers try to recover from, JSON parsers are zero-tolerance: one misplaced comma or an unquoted key and the entire parse fails.
This guide walks through every common JSON error, what causes it, and how to fix it in under a minute.
The 7 Most Common JSON Parse Errors
1. Trailing Comma
JSON does not allow a comma after the last element in an array or object. This is the single most common mistake — it's valid in JavaScript objects, so developers write it out of habit.
// ❌ Invalid
{
"name": "Alice",
"age": 30,
}
// ✅ Valid
{
"name": "Alice",
"age": 30
}
Error message: SyntaxError: Unexpected token } in JSON (the parser hits } where it expects another key-value pair)
2. Unquoted Keys
JSON requires double quotes around every key. JavaScript objects let you write bare keys ({name: "Alice"}), but that is not valid JSON.
// ❌ Invalid
{ name: "Alice" }
// ✅ Valid
{ "name": "Alice" }
Error message: SyntaxError: Unexpected token n in JSON at position 2
3. Single Quotes Instead of Double Quotes
Only double quotes are valid in JSON. Single-quoted strings fail silently in some editors but blow up at parse time.
// ❌ Invalid
{ "name": 'Alice' }
// ✅ Valid
{ "name": "Alice" }
4. Comments in JSON
JSON has no comment syntax. Neither // nor /* */ are valid. If you need annotated config files, use YAML or TOML instead.
// ❌ Invalid
{
// This is the user record
"name": "Alice"
}
If you're using JSON for config and want comments, consider JSON5 or convert to YAML.
5. Undefined, NaN, or Infinity Values
JSON only supports these value types: strings, numbers, booleans (true/false), null, arrays, and objects. JavaScript-only values like undefined, NaN, and Infinity are not valid JSON.
// ❌ Invalid
{ "score": NaN, "ratio": Infinity, "data": undefined }
// ✅ Valid — use null for missing values
{ "score": null, "ratio": null, "data": null }
In JavaScript: JSON.stringify({a: undefined}) silently drops the key. JSON.stringify({a: NaN}) outputs {"a":null}. Know this before you round-trip data.
6. Unexpected HTML or Plain Text in the Response
Unexpected token < in JSON at position 0 means your JSON parser received an HTML page instead of JSON — the < is the start of <!DOCTYPE html> or an error page.
This happens when:
- Your API endpoint returns an HTTP error page (404, 500) with HTML content
- A reverse proxy or CDN intercepts the request and returns its own error page
- You're hitting the wrong URL (missing base path, extra slash)
// Debug: log the raw response text before parsing
const res = await fetch('/api/data');
const text = await res.text();
console.log(text); // See what you're actually getting
const data = JSON.parse(text); // Now parse
Always check res.status and res.headers.get('content-type') before parsing.
7. Unescaped Special Characters in Strings
Certain characters inside a JSON string must be escaped with a backslash. A raw newline or tab inside a string value is invalid.
// ❌ Invalid — raw newline inside string
{ "message": "Hello
World" }
// ✅ Valid — escaped newline
{ "message": "Hello\nWorld" }
Characters that must be escaped: ", \, and control characters (\n, \r, \t, \b, \f). Unicode escapes (\uXXXX) are optional but valid.
Quick Reference: JSON Value Rules
| Type | Valid examples | Invalid |
|---|---|---|
| String | "hello", "" |
'hello', bare word |
| Number | 42, 3.14, -7, 1e10 |
NaN, Infinity, 0xFF |
| Boolean | true, false |
True, TRUE, yes |
| Null | null |
None, undefined, nil |
| Array | [1, 2, 3] |
[1, 2, 3,] (trailing comma) |
| Object | {"k": "v"} |
{k: "v"} (unquoted key) |
How to Validate JSON Quickly
Online: Paste your JSON into the JSON Formatter — it highlights the exact line and character where the error occurred.
Node.js:
try {
const data = JSON.parse(yourString);
} catch (e) {
console.error('Parse error at:', e.message);
// "Unexpected token , in JSON at position 45"
}
Python:
import json
try:
data = json.loads(your_string)
except json.JSONDecodeError as e:
print(f"Error at line {e.lineno}, col {e.colno}: {e.msg}")
Command line (jq):
echo '{"name": "Alice",}' | jq .
# parse error: Invalid numeric literal at line 1, column 20
Fixing JSON from External Sources
When you receive JSON from an API, a config file, or a database dump that fails to parse:
- Check the HTTP response status — a 200 doesn't guarantee JSON body
- Check
Content-Type— should beapplication/json - Log the raw string before parsing —
console.log(rawText.slice(0, 200)) - Run it through a linter — the JSON Formatter shows the exact error position
- Look for a BOM — some tools prepend a UTF-8 byte order mark (
\uFEFF), which breaksJSON.parsein older environments
Why JSON Is Strict by Design
JSON's strictness is a feature. Because the spec is unambiguous, a JSON string parsed in Go, Python, JavaScript, Rust, or Java produces the same data structure. If trailing commas or comments were allowed, every parser would have to decide how to handle edge cases, and interoperability would suffer.
If you want a more permissive format for config files, consider YAML (allows comments, multiline strings, anchors) or TOML (designed specifically for human-editable config). For data interchange between services, JSON's strictness is exactly what you want.
→ Validate and format your JSON with the JSON Formatter — highlights errors with line numbers and auto-indents valid JSON.