JSON is strict on purpose: a small, fixed grammar means every language parses it the same way. The price is that things that look fine to a human — a trailing comma, a comment, single quotes — make the whole document invalid. Here are the errors that come up most, what the parser is telling you, and how to fix each one.

Reading the parser's error

A parser stops at the first character that cannot continue a valid document. In JavaScript that looks like SyntaxError: Unexpected token } in JSON at position 42 (newer engines also report line and column). Two habits help:

  • Look just before the position. The parser reports where it gave up, which is often one character after the real mistake — the comma before a closing brace, for example.
  • "Unexpected end of JSON input" means the document stopped early: a missing } or ], or a truncated response body.

The common errors

1. Trailing commas

{ "name": "Ada", "role": "admin", }   ← invalid
{ "name": "Ada", "role": "admin" }    ← valid

JavaScript object literals allow a trailing comma; JSON does not. This is the most frequent error in hand-edited config files.

2. Single quotes

{ 'name': 'Ada' }     ← invalid
{ "name": "Ada" }     ← valid

Strings and keys must use double quotes. Single quotes usually mean the text was produced by printing a Python dict or a JS object, not by a JSON serializer.

3. Unquoted keys

{ name: "Ada" }       ← invalid

Every key is a string, so every key needs double quotes.

4. Comments

JSON has no comments. // … and /* … */ both fail. If a file genuinely needs comments (configuration), use a format that allows them — JSON5, JSONC, YAML or TOML — and make sure every tool reading it supports that format.

5. Special numbers and values

NaN, Infinity, undefined, hexadecimal (0xFF) and leading zeros (007) are not valid JSON. JSON.stringify silently turns NaN and Infinity into null, and drops keys whose value is undefined — so data can change shape without any error.

6. Unescaped characters in strings

Raw newlines, tabs and other control characters must be escaped (\n, \t) inside strings, and a backslash must be written \\. Windows paths are a common source: "C:\new" contains a newline escape, not the letters \n.

7. Several documents in one

{"a":1}{"b":2} is two documents, not one. Logs and streaming APIs often use JSON Lines — one JSON value per line — which must be parsed line by line, not as a single document.

A subtle one: large numbers

JSON itself allows numbers of any size, but JavaScript parses them into 64-bit floating point. Integers above 253 − 1 (9,007,199,254,740,991) lose precision silently:

JSON.parse('{"id": 9007199254740993}').id   // 9007199254740992

Large IDs (database snowflake IDs, some payment references) should be sent as strings. This is also one reason many APIs use UUIDs encoded as strings — see UUID v4 vs UUID v7.

When JSON5 is the right tool

JSON5 is a superset of JSON that allows comments, trailing commas, single quotes, unquoted keys and more. It is a good fit for files humans edit by hand. It is a poor fit for data exchanged between systems, because a strict JSON parser on the other side will reject it. Keep APIs on plain JSON.

Fixing and checking JSON quickly

The JSON Formatter on Zerethon Tools parses your input with the browser's own JSON.parse — so it accepts and rejects exactly what a real JavaScript client would — then pretty-prints it with your choice of indentation and optional key sorting. Everything happens in the browser, which matters when the JSON is an API response containing real data. For the relaxed format, the JSON5 Validator tells you whether a file is valid JSON5, and JSON Diff shows what changed between two payloads.