← Back to all articles

JSON Keeps Failing? Four Details That Trip Everyone

JSONPitfalls

JSON is not a JS object literal

JSON is a data interchange format and far stricter than JavaScript object literals: keys must be double-quoted, strings must use double quotes, no comments, and no trailing commas. Many errors come from pasting JS syntax straight into JSON.

The usual suspects

  • Trailing comma: [1, 2, 3,];
  • Single quotes: {'name': 1} should be double-quoted;
  • Unquoted keys: {name: 1} must be "name";
  • Comments: neither // nor /* */ is valid.

A fast debugging routine

  1. Read the error line/column — most parsers point right at it;
  2. Check the line above the error: a missing or extra comma is the usual root cause;
  3. Escape inner double quotes as ";
  4. When unsure, format first — clean indentation makes problems obvious.

Formatting and minifying

Format with 2-space indentation while developing, minify for transport. JSON containing sensitive data is best processed with a local tool instead of untrusted online services.

Valid vs invalid at a glance

PartJS object literalValid JSON
Key{name: 1}{"name": 1}
String'abc'"abc"
Trailing comma[1, 2,][1, 2]
Comments// noteNot supported
Special valuesundefined, NaNOnly null

Code example: parse safely

// Never parse untrusted input without error handling
function safeParse(text) {
  try {
    return { ok: true, data: JSON.parse(text) };
  } catch (e) {
    // e.message usually carries a position hint
    return { ok: false, error: e.message };
  }
}

// Validate and format from the command line (jq)
// jq . data.json     -> validate and pretty-print
// jq -c . data.json  -> minify to a single line

JSON vs YAML vs TOML

  • JSON: the de facto interchange standard — no comments, no multiline strings; ideal for APIs and generated config;
  • YAML: readable with comments, good for hand-edited config, but indentation-sensitive with implicit typing traps;
  • TOML: explicit and unambiguous — a good fit for project files such as Cargo.toml or pyproject.toml.

Follow-up questions

Large JSON feels slow? Minify it, project only the fields you need (jq '.items[] | {id, name}') and switch to streaming parsing if necessary. Does JSON preserve key order? The spec does not guarantee it — sort explicitly where order matters.

Real-world cases: three debugging scenarios

  1. "Intermittent JSON parse errors from an API": often an HTML error page or a BOM mixed into the response. Inspect the raw text, not just the console.
  2. "A large integer ID lost its last digits": JavaScript numbers are precise only to ~2^53, so a 19-digit order ID distorts after parsing. Fix: handle large integers as strings.
  3. "Adding a comment breaks it": standard JSON allows no comments, so the error is expected — do not sprinkle // in config files.

FAQ

Does formatting or minifying change the data? No, only whitespace and indentation. Which duplicate key wins? Parsers usually take the last one — a latent bug, so catch it early. JSON vs JSON5? JSON5 allows comments, single quotes and trailing commas, but generic parsers reject it — do not feed JSON5 as JSON. How do I find the syntax error? Use a formatter/validator that reports line and column — far faster than hunting commas by eye.

Try it: JSON formatter

Large files and streaming

  • Avoid loading it whole: parse multi-megabyte JSON with a streaming (SAX-style) parser rather than one JSON.parse on the entire string;
  • Structure first: parse only top-level keys and array lengths to confirm the shape before deciding to process it all;
  • Watch for a BOM: a UTF-8 BOM breaks direct parsing — strip it explicitly on read;
  • Never edit JSON with regex: substitutions can break escaping and nesting; parse, modify, then serialise.

Formatting conventions

Agree on indentation and key ordering: two-space indent, and keys either ordered by meaning or sorted before commit so diffs are not noise. Run formatting on save or in a pre-commit hook rather than relying on memory.

Numbers and precision traps

JSON does not distinguish integers from floats — 1.0 and 1 normalise to the same value in most parsers. Identifiers and money that must be exact are easily coerced into numbers and lose precision. As a rule, send integers above 2^53 and monetary amounts as strings.