MALFEN
4 min readMalfen

Fixing invalid JSON — the five errors that cause almost everything

Trailing commas, single quotes and unquoted keys account for most JSON failures. Here is how to recognise each one from the error message.

developersjsonguides

JSON has a famously small specification — the whole grammar fits on a business card. That is a feature, but it means the parser has no room to be forgiving, and its error messages are terse in a way that is not always helpful.

Nearly every invalid-JSON error comes down to one of five things.

1. The trailing comma

{
  "name": "Malfen",
  "tools": 25,
}

That comma after 25 is legal in JavaScript, legal in most modern languages, and invalid in JSON. Full stop.

The error you will see: Unexpected token } or Expected double-quoted property name.

It is the single most common JSON error, and it is particularly annoying because editors that format JavaScript happily add trailing commas for you. If a file was hand-edited or produced by concatenating strings, check the last item in every object and array.

2. Single quotes

{ 'name': 'Malfen' }

JSON requires double quotes. Not single quotes, not backticks, not the curly typographic quotes that a word processor will silently substitute.

The error you will see: Unexpected token '.

The curly-quote version is the cruel one, because " and " look almost identical in most fonts. If JSON was pasted through an email, a document or a chat client, this is a strong suspect.

3. Unquoted keys

{ name: "Malfen" }

Valid JavaScript. Invalid JSON. Keys are strings and strings need quotes — every time, including when the key is a single word with no special characters.

The error you will see: Expected property name enclosed in double quotes.

This one usually appears when someone copies an object literal out of source code and expects it to be JSON. It looks like JSON. It is not.

4. Comments

{
  // the number of tools
  "tools": 25
}

JSON has no comments. This was a deliberate decision by its designer, on the grounds that people would use comments to smuggle in parsing directives.

The error you will see: Unexpected token /.

If you need annotated configuration, use a format that supports it — JSON5, YAML, or TOML — or add a "_comment" key, which is ugly but valid.

5. The wrong kind of value

Several things that look like values are not valid JSON:

{
  "count": NaN,          // not a JSON value
  "big": Infinity,       // not a JSON value
  "hex": 0xFF,           // no hex literals
  "leading": .5,         // needs a leading zero: 0.5
  "trailing": 5.,        // needs a digit after the point
  "undef": undefined     // not a JSON value at all
}

JSON numbers are decimal only. The only literals are true, false and null.

NaN and Infinity are the ones that bite in practice, because they appear naturally in the output of numeric code and most serialisers will produce them without complaint.

Reading the error position

The most useful thing in a JSON error is the character position, and most parsers give you one:

Unexpected token } in JSON at position 47

Position 47 is the 47th character in the string — but that is measured across the whole document, including newlines, which makes it tedious to locate by hand. A formatter that converts the offset into a line and column number saves the counting.

One thing worth knowing: the reported position is where parsing failed, not necessarily where the mistake is. With an unclosed bracket, the parser happily continues until it reaches the end of the file and only then discovers the problem — so the error points at the last line while the actual missing brace is 200 lines earlier. When the position looks nonsensical, look upwards for something unclosed.

Escaping inside strings

Certain characters cannot appear literally inside a JSON string and must be escaped:

  • A double quote
  • A backslash
  • Literal newlines, tabs and carriage returns

A raw line break inside a string is invalid — it has to be written as the two-character escape sequence instead. This trips people up when embedding file paths or multi-line text by hand.

Duplicate keys

{ "name": "first", "name": "second" }

Technically valid, and technically undefined behaviour. The specification does not say what should happen. In practice almost every parser keeps the last value, silently discarding the first.

No error, no warning, and a genuinely difficult bug to find in a large configuration file — which is why a formatter that reports key counts is more useful than it sounds.

A quick checklist

When JSON will not parse:

  1. Search for ,} and ,] — trailing commas.
  2. Search for ' — single quotes.
  3. Check that every key is in double quotes.
  4. Search for // and /* — comments.
  5. Check for NaN, Infinity and undefined.
  6. If the error position is at the end of the file, look for an unclosed bracket or brace near the start.

That covers essentially every case. The rest is genuinely malformed data, and for that the line and column number is the fastest way in.