JSON.parse Unexpected Token — Trailing Commas and Copy-Paste Failures
Stack Overflow answer includes a trailing comma. Works in Chrome console because you pasted into an object literal, not through JSON.parse. Breaks CI on Friday when config hits Node. The error Unexpected token ] in JSON at position 847 is JSON’s way of saying “this is JavaScript cosplay, not JSON.”
- “JSON is JavaScript” — JSON is a subset. No comments, no trailing commas, no
undefined, noNaN, keys must be double-quoted strings. - “It works in VS Code” — VS Code JSONC mode allows comments; your production parser doesn’t.
- “I’ll use eval()” — Please don’t. Use a formatter, fix the syntax, or use
JSON5explicitly if you control the parser. - Blaming the API — Half the time the bug is copy-paste from a log line that truncated or escaped badly.
Top offenders (with examples)
1. Trailing comma
{
"name": "app",
"version": "1.0.0",
}
2. Single-quoted keys
{ 'id': 1 } // JS object literal — invalid JSON
{ "id": 1 } // valid JSON
3. Unescaped control characters in strings
Log copied a multiline stack trace into a "message" field without \n escaping.
4. NaN / Infinity
{ "score": NaN }
Invalid — use null or omit the field.
5. Hex or octal numbers
JSON numbers are decimal only — 0xFF fails.
Reading the error message
| Error snippet | Likely cause |
|---|---|
Unexpected token ] | Trailing comma in array |
Unexpected token } | Trailing comma in object |
Unexpected token ' | Single quotes |
Unexpected token u … undefined | undefined value |
Unexpected end of JSON input | Truncated paste, missing closing bracket |
Position number is byte offset — open in editor, go to column, or use a json formatter that highlights the line.
Debug workflow
- Paste into formatter — Local browser tool shows line/column of first error.
- Compare with schema — OpenAPI / Zod / JSON Schema expected shape vs actual.
- Minimize — Remove half the file until error disappears — binary search for large configs.
- Fix at source — If API returns bad JSON, fix server serializer; don’t patch client with regex forever.
- Add CI check —
jq . config.jsonorjsonlintin pipeline before deploy.
JavaScript vs JSON quick reference
| Feature | JS object literal | JSON |
|---|---|---|
| Trailing comma | Allowed (ES5+) | Not allowed |
| Comments | Allowed in JSONC | Not allowed |
| Keys | Unquoted or quoted | Double-quoted only |
| undefined | Allowed | Not allowed |
Config file hygiene
- Store env-specific JSON in separate files — don’t comment out keys with
//in.json. - Use
.jsoncextension + appropriate editor if you need comments — rename on build or use JSON5 loader explicitly. - Generate JSON from typed code (TypeScript, Zod) when possible — hand-edited JSON rots.
API responses that look like JSON but aren’t
Logs sometimes capture SSE lines (data: {...}) or NDJSON streams. Feeding the whole file into JSON.parse fails on line 2. Parse line-by-line or strip data: prefixes first. GraphQL errors wrapped in HTML error pages also produce “Unexpected token <” — that’s your CDN login page, not malformed JSON.
Tool: validate before deploy
The json-formatter tool validates, formats, and minifies JSON in your browser — catch trailing commas before they hit production.
TL;DR
JSON.parse is strict. Trailing commas and single quotes are the usual suspects. Format locally, read line numbers, fix at source, add CI validation.