Start by pasting the document into the validator to get the exact line and column. Then match the failure against these seven patterns - they cover the overwhelming majority of real-world breakage.
1. Trailing comma
// Broken: comma after the last item
{ "a": 1, "b": 2, }
// Fixed
{ "a": 1, "b": 2 }
JavaScript allows trailing commas; JSON never does. If the error points at a closing brace or bracket, look immediately before it.
2. Single quotes
// Broken
{ 'name': 'Ada' }
// Fixed
{ "name": "Ada" }
JSON strings and keys demand double quotes. Python repr output and hand-typed snippets are the usual sources of single quotes.
3. Unquoted keys
// Broken: JavaScript object literal
{ name: "Ada" }
// Fixed
{ "name": "Ada" }
Bare words are legal in JavaScript and YAML but not in JSON. Quote every key.
4. Comments
// Broken
{
// user record
"name": "Ada"
}
// Fixed: delete the comment, or keep it as data
{
"_comment": "user record",
"name": "Ada"
}
5. Truncated paste
// Broken: ends mid-document
{ "users": [{ "name": "Ada" }
// Fixed: close every opened bracket
{ "users": [{ "name": "Ada" }] }
"Unexpected end of JSON input" always means truncation: a clipped copy, a capped log line, or a download that stopped early. Count opening versus closing brackets.
6. Non-JSON literals
// Broken: JavaScript values
{ "a": undefined, "b": NaN }
// Fixed
{ "a": null, "b": null }
undefined, NaN, and Infinity exist in JavaScript but not in JSON. The equivalent is almost always null.
7. Bad escapes and smart quotes
// Broken: raw newline and curly quotes
{ "text": "line one
line two", “key”: 1 }
// Fixed
{ "text": "line one\nline two", "key": 1 }
Control characters must be escaped (\n, \t, \"), and word processors love replacing straight quotes with curly ones. Paste through a plain-text editor when in doubt.