JSON Parse Errors: The Most Common Mistakes and How to Read the Error

"Invalid JSON" is one of the least helpful-sounding error messages around, but the browser actually tells you exactly where it gave up — the trouble is usually reading that position correctly, and knowing which of a handful of near-misses caused it. The JSON Formatter uses your browser's own built-in JSON.parse, with no relaxed or forgiving mode, so every error shown is exactly what a real application parsing your JSON would hit too.

Strict JSON, not "whatever JavaScript accepts"

It's easy to assume JSON and a JavaScript object literal are the same thing, since JSON syntax was originally based on it — but JSON (formally, a data format defined by RFC 8259) is stricter than JavaScript's own object syntax. JavaScript accepts single quotes, unquoted keys, trailing commas, and comments in an object literal. JSON.parse accepts none of them. Every one of the mistakes below is valid-looking JavaScript that isn't valid JSON.

The common mistakes, with fixes

MistakeExampleFix
Trailing comma{"a": 1, "b": 2,}Remove the comma after the last item: {"a": 1, "b": 2}
Single quotes{'a': 1}Use double quotes for both keys and strings: {"a": 1}
Unquoted key{a: 1}Every key must be a double-quoted string: {"a": 1}
Comments{"a": 1 /* note */}JSON has no comment syntax at all — remove it entirely.
NaN / undefined{"a": NaN}Neither is valid JSON. Use null, or omit the key.
Byte-order mark (BOM)An invisible character before the first {Usually comes from Windows/Excel exports — re-save the file as UTF-8 without a BOM, or paste into a plain text editor first to strip it.

Duplicate keys: not actually an error

This one is worth knowing precisely, because it's the opposite of what you might expect: {"a": 1, "a": 2} is valid JSON. JSON.parse doesn't reject duplicate keys — it silently keeps the last value and discards the earlier ones, parsing to {"a": 2} with no error or warning at all. If you're debugging why a value seems to have "disappeared" after parsing, a duplicate key earlier in the object — easy to miss in a large file — is a common, silent cause. Pretty-printing the JSON first makes duplicate keys far easier to spot visually, since each one lands on its own line.

Reading where the parser stopped

A message like "Unexpected token ',' at position 16" is more useful than it looks. "Position 16" counts characters from the very start of your input (starting at 0), including all whitespace and line breaks — so for a short, single-line snippet you can literally count characters to the trouble spot. For anything longer, it's faster to pretty-print the JSON first (which reformats it onto multiple, indented lines) and look at the "line" and "column" numbers most browsers include alongside the position, rather than counting through a wall of minified text by hand.

One habit worth building: the position reported is usually where the parser first noticed something was wrong, which is often slightly after the actual mistake — a missing comma is reported at the token that comes next, not at the empty space where the comma should have been. If the character the error points to looks completely fine, check just before it.

JSON vs. JavaScript objects vs. YAML

These three are easy to blur together, but each is more or less permissive than the last. JSON is the strictest: double-quoted keys and strings only, no comments, no trailing commas, no functions, no undefined. A JavaScript object literal is JSON's superset — everything valid in JSON also happens to be valid JS object syntax (that's exactly why it's tempting to write JSON by hand as if the rules were the same), plus single quotes, unquoted keys, trailing commas, comments, and values JSON can't represent at all, like functions or undefined. YAML is the most permissive of the three, and it's worth knowing that converting FROM YAML strips things JSON simply can't hold — YAML's comments don't survive a conversion to JSON, because JSON has no concept of comments whatsoever. The YAML ↔ JSON Converter handles that translation directly if you need to move between the two.

Pretty vs. minified

Pretty-printing adds indentation and line breaks purely for human readability — it changes nothing about the data. Minifying strips every unnecessary space, tab, and line break to make the file as small as possible for sending over a network, at the cost of being much harder to read. Both represent the exact same underlying data; switching between them with JSON Formatter is purely cosmetic and never changes a value.

Large numbers lose precision, silently

JSON's number type has no explicit size limit, but JavaScript (and therefore JSON.parse) stores every number as a 64-bit floating-point value, which can represent whole numbers exactly only up to 2⁵³ − 1 (9,007,199,254,740,991). Parse {"id": 9007199254740993} — one past that limit — and you silently get back 9007199254740992, a different number, with no error or warning of any kind. This bites people most often with large database IDs, 64-bit tokens, or hashes stored as JSON numbers rather than strings. If a large ID needs to survive a round trip exactly, store it as a JSON string instead of a number. This is the same numeric limit the Number Base Converter runs into when converting very large values between bases.

Try it yourself

JSON Formatter & ValidatorPretty-print, minify, and validate JSON, with the exact parse error if it's invalid.

Also useful: YAML to JSON Converter, CSV to JSON Converter, JSON to CSV Converter.