How to Fix "Unexpected token in JSON" Errors
A practical guide to diagnosing and fixing the JavaScript SyntaxError family — from "unexpected token o" to "unexpected end of JSON input" — with before-and-after code you can copy.
What the error actually means
Every "Unexpected token ... in JSON" message is a SyntaxError thrown by JSON.parse(). It means the string you handed to the parser is not valid JSON. The parser reads the text character by character, and the moment it hits something it cannot make sense of, it stops and reports that character.
The message usually points to the exact spot — for example Unexpected token o in JSON at position 1 or Unexpected end of JSON input. The token it names and the position it gives are your two biggest clues. Read them literally: they tell you which character broke parsing and where it sits in the string.
"Unexpected token o in JSON at position 1"
This is the most common one, and it is almost always a sign you passed an object or array to JSON.parse() instead of a string. JSON.parse() expects text, so JavaScript first coerces your object to a string, producing [object Object]. The parser reads the first character [, then hits o at position 1 — hence the "token o".
// Wrong — data is already an object
const data = { name: 'Ada' };
JSON.parse(data); // SyntaxError: Unexpected token o in JSON at position 1
// Right — only parse actual JSON strings
const text = '{"name":"Ada"}';
const obj = JSON.parse(text); // { name: 'Ada' }The classic version of this happens with fetch. Calling res.json() already parses the body for you, so parsing it again double-parses an object:
// Wrong — res.json() already returns parsed data
const data = await res.json();
const obj = JSON.parse(data); // SyntaxError: Unexpected token o
// Right — use it directly, no second parse
const obj = await res.json();Rule of thumb: only call JSON.parse() on raw text. If a value is already an object, you are done — do not parse it again.
"Unexpected end of JSON input"
This message means the parser reached the end of the string before the JSON was complete. The usual causes are an empty string, a truncated response (the network call failed or returned nothing), or JSON that is missing its closing brace or bracket.
JSON.parse(''); // SyntaxError: Unexpected end of JSON input
JSON.parse('{"a":1'); // SyntaxError: Unexpected end of JSON input
JSON.parse(localStorage.getItem('missing')); // null -> throwsGuard against empty or missing input before you parse, and supply a sensible fallback:
function parseOrDefault(text, fallback = null) {
if (!text || !text.trim()) return fallback;
try {
return JSON.parse(text);
} catch {
return fallback;
}
}"Unexpected token < in JSON"
When the token is <, the server almost certainly returned HTML instead of JSON — that first < is the start of <!DOCTYPE html> or <html>. This typically happens when a request hits a 404 page, a login redirect, or a server error page rather than your API endpoint.
Check res.ok and the response content type before parsing, and log the raw text when something looks off:
const res = await fetch('/api/users');
if (!res.ok) {
throw new Error('Request failed: ' + res.status);
}
const type = res.headers.get('content-type') || '';
if (!type.includes('application/json')) {
const raw = await res.text();
console.error('Expected JSON, got:', raw.slice(0, 200));
throw new Error('Response was not JSON');
}
const data = await res.json();Trailing commas, single quotes, and unquoted keys
JSON is stricter than a JavaScript object literal. Three habits carried over from JavaScript all throw "Unexpected token" errors: trailing commas, single quotes, and unquoted keys.
// Invalid JSON
{
name: 'Ada', // unquoted key + single quotes
roles: ['admin',], // trailing comma
}The valid version uses double quotes everywhere — on both keys and string values — and removes the trailing comma:
// Valid JSON
{
"name": "Ada",
"roles": ["admin"]
}Comments are not allowed in JSON either, and the only valid quote character is the double quote. Our common JSON errors guide walks through each of these in detail.
How to debug it fast
When you are staring at an "Unexpected token" error, three steps usually pin it down in under a minute:
- Log the raw string right before you parse it. Seeing the actual text — empty, HTML, or already an object — often answers the question instantly.
- Paste it into a validator to jump straight to the exact position the error names, with the offending character highlighted.
- Wrap JSON.parse() in try/catch so a bad payload degrades gracefully instead of crashing your app.
console.log('Raw input:', JSON.stringify(text));
try {
const data = JSON.parse(text);
} catch (err) {
console.error('Parse failed:', err.message);
}For a deeper look at what JSON.parse() expects and how it works, see our JSON.parse() guide.
Pinpoint the exact token that breaks your JSON
Paste the broken JSON into our free formatter to jump straight to the failing position, highlight the unexpected token, and auto-fix common mistakes — no more guessing where the error is.
Open JSON Formatter