Unexpected token } in JSON at position 412. No line number, no context, just a position to count by hand. Every developer meets this error monthly; the fix takes seconds once you know the three causes that produce 90% of failures: trailing commas, comments, and single quotes. This guide teaches reading the error, fixing each cause, and validating at scale — with the line:column pinpointing that turns counting into clicking.
Part of the developer toolkit guide. Validate in the JSON formatter; inspect trees in the JSON tree viewer; convert configs in JSON to YAML.
Read the error: position → line:column
V8 reports a character offset, not a location. Pasting into the formatter translates position 412 to line 18, column 7 with the offending token highlighted — and names the cause class. The 500KB API reply that defeats eyeballing submits instantly; collapse completed subtrees to isolate the broken branch. For recurring feeds, validate on a schedule and diff against the last green payload — most production JSON breaks come from upstream schema drift, not your code.
Three causes, three fixes (with examples)
| Cause | Broken | Fixed |
|---|---|---|
| Trailing comma | {"a": 1,} | {"a": 1} — minify to confirm |
| Comments | {// x | Strip all comments (JSONC ≠ JSON) |
| Single quotes | {'a': 1} | Double-quote keys + strings |
| Duplicate keys | {"a":1,"a":2} | Dedupe — last wins silently |
After fixing, minify and re-pretty-print: a clean round-trip proves validity better than any single check. Payloads over 10MB should split before pasting — oversized dumps hang tabs in every tool, not just ours.
At scale: 500KB replies, duplicate keys, minify math
Large API responses fail differently: truncated transfers (compare Content-Length), duplicated keys across merged objects (last-wins silently corrupts), and encoding mismatches (BOM prefixes break strict parsers — strip \uFEFF). Minified output runs ~20% smaller than pretty-printed — meaningful at 500KB over metered connections. Keep a known-good sample response per endpoint; when parse fails, diff structure first (added field? renamed key?) and syntax second. For config files, consider YAML source with JSON build output — humans edit YAML, machines consume JSON, and the converter bridges them.
General guidance only. Validate untrusted payloads before processing — malformed JSON is also a classic injection vector; parse strictly, never eval.