JSON is everywhere a program needs to hand data to another program: API responses, config files, log lines, message queues. It is small enough to learn in an afternoon, which is exactly why people skip learning it properly and then spend an hour staring at
Unexpected token } in JSON at position 142What JSON Actually Is
JSON (JavaScript Object Notation) is a text format for structured data. It looks like a subset of JavaScript object literals, but it is a strict, language-independent standard. Parsers in Python, Go, Rust, and Java all expect the same exact rules. The grammar is deliberately tiny, and most bugs come from treating it as if it were JavaScript, YAML, or a Python
dictA valid JSON document is exactly one value. That value is usually an object or an array, but a bare string, number,
truefalsenull42"hello"The Six Value Types
JSON has exactly six types and no more:
- Object — an unordered set of key/value pairs wrapped in text
{ } - Array — an ordered list wrapped in text
[ ] - String — text in double quotes: text
"text" - Number — ,text
42,text-3.14(no leadingtext6.022e23, no leading zeros, notext+, notextNaN)textInfinity - Boolean — ortext
true, lowercase onlytextfalse - Null — , lowercase onlytext
null
That is the entire type system. There is no date type, no integer-vs-float distinction at the spec level, no comments, and no trailing commas. Anything outside this list is not JSON, even if your editor highlights it nicely.
Objects
An object is zero or more key/value pairs. Keys must be strings in double quotes. Values can be any of the six types, including nested objects and arrays.
json{ "name": "Ada", "active": true, "projects": 3, "manager": null, "address": { "city": "London", "zip": "SW1A" } }
Keys are not required to be unique by the spec, but if you repeat a key most parsers keep the last one and silently drop the rest — a quiet source of bugs. Treat keys as unique.
Arrays
An array is an ordered list of values. The values do not have to share a type, though keeping them homogeneous makes the data far easier to consume.
json{ "tags": ["data", "json", "parsing"], "scores": [98, 87.5, 100], "mixed": [1, "two", true, null] }
Empty objects
{}[]The Errors You Will Actually Hit
Nearly every JSON parse failure is one of a handful of mistakes. Here they are, with the fix for each.
Trailing Commas
This is the single most common JSON error, because JavaScript, Python, and most modern languages allow trailing commas in their own literals. JSON does not. A comma separates items; it must be followed by another item, never by a closing bracket.
json{ "a": 1, "b": 2, }
The comma after
2json{ "a": 1, "b": 2 }
The same applies inside arrays —
[1, 2, 3,]Single Quotes
JSON strings and keys must use double quotes. Single quotes are a JavaScript and Python habit that the JSON grammar simply does not include.
json{ 'name': 'Ada' }
Fixed:
json{ "name": "Ada" }
If your text contains a double quote, escape it with a backslash:
"She said \"hi\""Unquoted Keys
In JavaScript you can write
{ name: "Ada" }json{ name: "Ada", active: true }
Fixed:
json{ "name": "Ada", "active": true }
This one is common when someone copies an object literal out of source code and tries to use it as a config file. Quote every key.
Comments
JSON has no comment syntax. Not
///* */#json{ // database connection "host": "localhost", "port": 5432 }
The
//json{ "_comment": "database connection", "host": "localhost", "port": 5432 }
A
_commentWrong Literals for null and Booleans
nulltruefalseNULLNoneTrueFalseniljson{ "manager": None, "active": True }
Fixed:
json{ "manager": null, "active": true }
This is the classic mistake when someone pastes a Python
repr()dictNumber Formatting
JSON numbers are stricter than they look. No leading zeros (
017+NaNInfinityJSON.stringify(NaN)"null"json{ "a": 01, "b": +5, "c": 3. }
Fixed:
json{ "a": 1, "b": 5, "c": 3.0 }
Unescaped Control Characters
A literal newline or tab inside a string must be escaped as
\n\tjson{ "note": "line one line two" }
Fixed:
json{ "note": "line one\nline two" }
How to Read a Parser Error Message
The error text looks cryptic but almost always points you straight at the problem. Two pieces of information matter: the position and the token.
Position. Messages like
at position 142line 7 column 3}Token.
Unexpected token } in JSON}Unexpected stringExpected ',' or '}'Unexpected end of JSON inputHere is the mental translation table:
- /text
Unexpected token }→ trailing comma right before ittext] - on a key → unquoted key or single quotestext
Unexpected token - → you forgot a comma between two pairstext
Expected ',' or '}' - → an unclosedtext
Unexpected end of input,text{, ortext[text" - → two values where one is allowed, or a stray character at the endtext
Unexpected non-whitespace character after JSON
The line/column numbers from compiled-language parsers (Go, Rust, Java) tend to be more precise than the byte-offset numbers from older JavaScript engines, but both point to roughly the same spot. Trust the location, then scan upward a line or two.
A Workflow That Catches These Fast
Reading positions by hand works for a 10-line file. For a 4,000-line API response it does not. A few habits make JSON debugging almost mechanical:
- Format before you read. Minified JSON hides structure. Pretty-printing it with consistent indentation makes a missing bracket or stray comma jump out visually. Our JSON formatter does this in the browser and reports the first parse error with its location, which is faster than squinting at a one-line blob. It runs entirely client-side, so you can paste data you would not want to send to a server.
- Validate, do not eyeball. A validator confirms the whole document parses, not just the part you are looking at. Fix the first reported error, re-validate, repeat — errors often cascade, and the second one only appears once the first is gone.
- Generate, do not hand-write. If your code emits JSON, use the language's serializer (,text
json.dumps,textJSON.stringify) rather than building strings. Serializers cannot produce trailing commas, unquoted keys, or single quotes.textencoding/json - Convert when you need a different shape. Once your JSON is valid, you often want it somewhere else — a spreadsheet, a database import, a quick scan in a table. Converting an array of objects to a flat table with a JSON to CSV tool is usually faster than writing a one-off script, and it surfaces inconsistent keys across records as a side effect.
The Short Version
JSON is strict on purpose — that strictness is what lets every language agree on what the data means. Memorize the six types, use double quotes everywhere, never leave a trailing comma, never add comments, and keep
nulltruefalse