Web Toolkit

How to read and fix broken JSON

Almost every JSON parse error comes from one of five mistakes. Here is how to find which one, from the error message alone.

Last updated 30 July 2026

A JSON parser gives you one sentence when it fails, and that sentence is usually blamed for being useless. It is not useless — it is just terse. Unexpected token } in JSON at position 1482 tells you exactly where the parser gave up, and the mistake is almost always a few characters before that point.

The order of operations that actually works is: format first, read the position, then look for one of five specific mistakes.

Format before you read

Minified JSON is not human-readable, and reading it is not a skill worth acquiring. Indentation turns a structural problem into a visible one: a missing closing brace shows up as an indentation level that never returns to zero, and a value nested one level too deep is obvious the moment the shape is laid out.

This is also why the formatter reports the failure position rather than only refusing to work. A parser that says "invalid" without saying where has thrown away the only information you needed.

The five mistakes

A trailing comma. {"a": 1, "b": 2,} is valid JavaScript and invalid JSON. This is the single most common cause, and it is the one people trust least because the object looks fine. JSON has no trailing commas anywhere — not in objects, not in arrays. If your error position points at a } or a ], look at the character before it.

Single quotes. {'name': 'Ada'} is a Python dictionary or a JavaScript object literal, not JSON. The JSON specification allows double quotes only, for both keys and string values. This one usually appears when someone has pasted a log line where a language printed its own native representation of an object rather than serialising it.

Unquoted keys. {name: "Ada"} has the same origin: JavaScript allows it, JSON does not. Every key is a quoted string.

An unescaped character inside a string. A literal newline, tab or unescaped backslash inside a string value breaks the string. Windows paths are the classic case: "C:\\Users\\ada" is correct because every backslash is doubled, while "C:\Users\ada" fails at the U. Control characters must be escaped as \n, \t, \r.

Something that is not JSON at all. An error at position 0 or 1 rarely means the JSON is malformed — it means the thing you pasted is not JSON. A truncated response, an HTML error page from a proxy, a PHP notice printed before the payload, or NaN / undefined / Infinity emitted by a language that considers those values printable. Read the first line literally before assuming the parser is confused.

What "valid" does not mean

A document can parse cleanly and still be wrong for your purpose. Three things worth checking after the parse succeeds:

  • Numbers. JSON numbers are IEEE-754 doubles in most parsers, so an ID longer than 15–16 digits silently loses precision. Large identifiers belong in strings. If a value comes back as 9007199254740993 when it went out as 9007199254740992, this is why.
  • Duplicate keys. The specification does not forbid them, and most parsers keep the last one silently. If a config behaves as though your setting was ignored, look for the same key twice.
  • Encoding. JSON is UTF-8 by definition. A file saved as Latin-1 will parse and then produce mojibake in every string containing an accent.

When it is a JWT, not JSON

A three-part string separated by dots is a JSON Web Token, and pasting it into a JSON formatter will always fail — the parts are Base64url-encoded, and only the first two decode to JSON at all. Decode it as a token, which also lets you read the exp claim, the single most common reason a "valid" token is being rejected.

When it is YAML, not JSON

Every JSON document is valid YAML, but not the reverse — so a YAML file with comments, anchors or unquoted multi-line strings will never parse as JSON. Errors in YAML are structurally different too: they are usually about indentation, and a tab character anywhere in the indentation is a hard failure because YAML forbids tabs for indenting. If a YAML file "looks identical" to a working one and still fails, check for tabs before checking anything else.

Tools used in this guide

All guides