What the error message tells you
Modern V8 (Chrome / Node) reports errors like:
SyntaxError: Unexpected token } in JSON at position 42 (line 4 column 1) Three pieces matter:
- The token character (
}here) — the character that broke the parser, not necessarily the character that's wrong. The actual mistake is usually just before this position. - The position — a zero-indexed character offset into the input.
- Line and column — what humans want. Older Node versions and Safari only give you the position; you have to walk the input yourself to translate.
Our linter does the translation for you and shows the exact line and column for any error.
The seven most common causes
1. Trailing comma
By far the most frequent cause. JSON does not allow a trailing comma
before } or ]. Many programmers reach for
JSON after writing JavaScript object literals (which do allow it) and
get caught.
{
"name": "Eli",
"items": [1, 2, 3,] ← trailing comma after 3
} Fix: remove the comma. If you can't control the producer, run the input through a JSON5 parser instead.
2. Single quotes instead of double
JSON strings must use double quotes. Single quotes are valid JS but invalid JSON.
{ 'name': 'Eli' }
Fix: replace all single quotes with double. If your data contains
legitimate apostrophes, escape them: "can't" or
leave them inside double-quoted strings unescaped.
3. Unquoted keys
JS lets you write { name: "Eli" }. JSON requires
every key to be a quoted string.
{ name: "Eli" } ← keys must be in double quotes 4. Comments
JSON has no comment syntax. Both // and /* */
will trip JSON.parse. If you need comments, use JSONC
(used by VS Code's settings) or JSON5 — but most APIs reject both.
5. The response wasn't JSON at all
If you see Unexpected token < in JSON at position 0,
the response started with < — almost always an HTML
error page from a misbehaving API. Check status code and
Content-Type before parsing:
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
if (!res.headers.get("content-type")?.includes("application/json")) {
throw new Error("Expected JSON, got " + res.headers.get("content-type"));
}
return res.json(); Unexpected token U at position 0 usually means the input
was the literal string undefined. Look for an upstream
function that returned undefined instead of a JSON
payload (e.g. localStorage.getItem for a missing key).
6. BOM or hidden whitespace
UTF-8 byte-order marks () at the start of a file
will trip JSON.parse. Files saved by some Windows tools
include a BOM by default. Strip it before parsing:
JSON.parse(text.replace(/^/, "")) 7. Mismatched / missing brackets
A missing } or ] often surfaces with the
token reported as the very next character (or end of input) — far
from where the actual mistake is. The linter helps by highlighting
the exact line where the parser gave up so you can scan upward.
Three rules that prevent most of these
- Don't hand-write JSON for anything more than a
one-line config. Use
JSON.stringify(value, null, 2)in your producer. - Lint at the boundary. Validate JSON immediately after fetching, reading from disk, or receiving from a queue — before passing it deeper into your code.
- Use a typed schema (Zod, valibot, JSON Schema) once the shape matters. Catches the cases JSON.parse can't, like a missing required field or wrong type.
Reference
Strict JSON is defined by RFC 8259 (the current standard, replacing 7159 / 4627). Common relaxed variants:
- JSONC — JSON with comments. Used by VS Code's
settings.jsonandtsconfig.json. No trailing commas. - JSON5 — comments, trailing commas, single quotes, unquoted keys. Closer to JS object literal syntax.
- NDJSON / JSON Lines — one JSON value per line, no outer array. Great for streaming. Each line is parsed individually.
FAQ
What causes 'Unexpected token U in JSON at position 0'?
The string you're trying to parse starts with the word 'undefined' or another non-JSON value. The first 'U' is what the parser stumbled on. This usually means an upstream function returned undefined instead of a JSON string.
Why does my JSON fail in JavaScript but work in Python?
Python's json module historically tolerated some JSON5-style features. JavaScript's JSON.parse follows RFC 8259 strictly: no comments, no trailing commas, no single quotes, no unquoted keys. If your JSON came from Python's repr() or pprint(), it's probably Python dict syntax, not JSON.
Can I make JSON.parse accept comments or trailing commas?
Not directly. If you control the producer, fix the JSON. If you don't, parse with a JSON5 library (json5 on npm) or strip comments and trailing commas with a regex pre-pass. JSONC (JSON with Comments, used by VS Code) and JSON5 are both common alternatives.
Why do I get this error from fetch().json()?
fetch().json() runs JSON.parse on the response body. If the server returned HTML (like an error page) instead of JSON, the first character is usually '<', so you'll see 'Unexpected token <'. Check response.ok and response.headers.get('content-type') before calling .json().
Does the position number count characters or bytes?
Characters, including newlines. Tools that count bytes will give a different number for input containing multi-byte characters (emoji, non-ASCII). The position-to-line/column math walks the input one character at a time.