Posted in Blog · Reading time ~8 min

How to fix the most common JSON parse errors

JSON looks easy. It's a few brackets, quotes, commas, and colons. And yet, the same handful of errors trip up every developer at some point, especially when JSON is generated by something that wasn't quite trying. Here's a tour of the ones we see most often, what they look like, and the smallest fix for each.

If you want to try them as you read, our JSON Validator will pinpoint the exact line and column of each error, and Repair mode can patch most of them automatically. For schema-shape problems (rather than syntax), use the JSON Schema Validator.

1. Trailing comma

This is the most common JSON error in the world.

{
  "name": "Alice",
  "role": "admin",
}

That comma after "admin" is illegal. JavaScript allows trailing commas in object and array literals; JSON does not. JSON.parse will reject it with something like:

SyntaxError: Unexpected token } in JSON at position 41

Fix: remove the comma. If you can't change the producer, use a tolerant parser (Python's json5, JavaScript's JSON5, or JSONYard's Repair mode).

2. Single quotes around strings or keys

{ 'name': 'Alice' }

JSON requires double quotes — for both keys and string values. Single-quote support is a JS-ism that snuck into people's mental model of JSON. The fix is a find-and-replace, but be careful: a naive replace breaks strings that contain apostrophes.

Quick sed-ish recipe in a pinch:

cat in.json | python -c "import json,sys; print(json.dumps(eval(sys.stdin.read())))"

… but eval is dangerous for untrusted input. Prefer a tolerant parser.

3. Comments

{
  // This is a config file
  "debug": true
}

JSON has no comment syntax. Several "JSON with comments" flavors exist (JSONC, JSON5, HJSON), and editors like VS Code use JSONC for their settings — but standard tooling rejects them. The cleanest fix: strip // and /* */ before passing the text to JSON.parse, or pre-process with a tolerant parser.

4. Unquoted keys

{ name: "Alice" }

Looks like a JS object literal, isn't valid JSON. Wrap every key in double quotes.

5. Unescaped characters in a string

{ "path": "C:\Users\alice" }

JSON requires backslashes to be escaped. \U isn't a known escape, so this fails. Either escape each backslash ("C:\\Users\\alice") or use forward slashes ("C:/Users/alice").

Less obvious cousins:

  • Newlines in strings — must be \n, not a raw newline.
  • Tabs — must be \t.
  • Internal double quotes — must be \".

6. The quiet ones: BOM, NBSP, smart quotes

These ruin your day silently.

  • UTF-8 BOM — the byte sequence 0xEF 0xBB 0xBF at the start of the file. Many parsers reject it. Save without a BOM, or strip the first three bytes.
  • Non-breaking spaces (NBSP, U+00A0) — copied from a PDF or chat. They look identical to spaces but aren't. The parser may complain about an "unexpected token". Run the input through a tool that normalizes whitespace.
  • Smart quotes“ ” instead of " ". Common when copying from email or Word. They look like quotes but they're U+201C and U+201D. Replace them with straight ASCII quotes.

The validator's error message ("unexpected token") gives no hint about which one. If you can't see the problem, paste into a hex viewer or do a quick replace of the usual suspects:

// JS one-liner: strip BOM, normalize quotes and NBSPs
text.replace(/^/, '')
    .replace(/[“”]/g, '"')
    .replace(/[‘’]/g, "'")
    .replace(/ /g, ' ');

7. The whole response was HTML, not JSON

You called an API, the server returned an error page, and your client tried to parse <!doctype html> as JSON. The parse error you get is usually Unexpected token < in JSON at position 0 — a classic. Fix: check the HTTP status code before parsing. If it's not 2xx, the body probably isn't JSON regardless of the Content-Type.

8. NaN, Infinity, undefined

JSON has no representation for these. JSON.stringify turns them into null for arrays and drops them entirely for object values. If you see them appearing as literals in your input, the producer was buggy. Replace with null or remove.

9. Numbers larger than 253−1

This one is sneaky because the JSON parses. It just loses precision.

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

JavaScript represents numbers as 64-bit floats. Integers past Number.MAX_SAFE_INTEGER lose digits. Big IDs (Twitter IDs, Snowflakes, MongoDB ObjectIds-as-bigint) need to be sent as strings.

10. Duplicate keys

{ "a": 1, "a": 2 }

Technically valid JSON, technically undefined behavior. Most parsers keep the last value. If you rely on the first, you'll be surprised. Don't produce duplicates; if you can't avoid it, make the dedupe rule explicit on your side.

The lesson

Most "broken JSON" isn't broken in the spec sense — it was produced by someone who thought JSON was a superset of JavaScript object literals. It isn't. JSON is small and unforgiving, and that's its strength.

When you find broken JSON in the wild, paste it into the JSON Validator and let Repair mode try first. If you have to do the fix by hand, the list above is in roughly descending order of frequency — start at the top.

Have an error not on this list that keeps tripping you up? Tell us and we'll add it.