The error SyntaxError: Unexpected token in JSON occurs when JSON.parse() receives invalid JSON data. JSON must follow strict formatting rules, and any deviation causes this error.
// ⌠Problem - Invalid JSON
JSON.parse("{'name': 'John'}"); // Single quotes - Error!
// ✅ Solution - Valid JSON with double quotes
JSON.parse('{"name": "John"}'); // Works!
// ✅ Solution - Use try-catch
try {
const data = JSON.parse(jsonString);
console.log(data);
} catch (error) {
console.error('Invalid JSON:', error);
}
JSON requires double quotes for strings. Single quotes are not valid JSON.
Trying to parse an object that's already a JavaScript object, not a JSON string.
JSON doesn't allow trailing commas, unlike JavaScript objects.
Trying to parse non-JSON content like HTML error pages or plain text.
JSON doesn't support undefined, functions, or other JavaScript-specific types.
// Invalid JSON - single quotes
const jsonString = "{'name': 'John', 'age': 30}";
JSON.parse(jsonString); // SyntaxError!
// Also invalid - unquoted keys
const jsonString2 = "{name: 'John'}";
JSON.parse(jsonString2); // SyntaxError!
// Valid JSON - double quotes for both keys and values
const jsonString = '{"name": "John", "age": 30}';
const data = JSON.parse(jsonString);
console.log(data); // { name: 'John', age: 30 }
// Or use template literals with double quotes inside
const jsonString2 = `{"name": "John", "age": 30}`;
const data2 = JSON.parse(jsonString2);
// Already a JavaScript object
const user = { name: 'John', age: 30 };
JSON.parse(user); // SyntaxError: Unexpected token o in JSON
// Or from API that already returns object
fetch('/api/user')
.then(res => res.json()) // Already parsed here
.then(data => {
const parsed = JSON.parse(data); // Error! Already an object
});
// Don't parse if already an object
const user = { name: 'John', age: 30 };
console.log(user); // Use directly
// Check type before parsing
function safeParse(data) {
if (typeof data === 'string') {
return JSON.parse(data);
}
return data; // Already an object
}
// With fetch, don't double-parse
fetch('/api/user')
.then(res => res.json()) // Parse once
.then(data => {
console.log(data); // Use directly, don't parse again
});
// Trailing comma in object
const jsonString = '{"name": "John", "age": 30,}';
JSON.parse(jsonString); // SyntaxError!
// Trailing comma in array
const jsonString2 = '["apple", "banana", "orange",]';
JSON.parse(jsonString2); // SyntaxError!
// Remove trailing commas
const jsonString = '{"name": "John", "age": 30}'; // No trailing comma
JSON.parse(jsonString); // Works!
const jsonString2 = '["apple", "banana", "orange"]'; // No trailing comma
JSON.parse(jsonString2); // Works!
// Or clean the string before parsing
function cleanJSON(str) {
return str.replace(/,(\s*[}\]])/g, '$1'); // Remove trailing commas
}
const dirty = '{"name": "John",}';
const clean = cleanJSON(dirty);
JSON.parse(clean); // Works!
// API returns HTML error page instead of JSON
fetch('/api/user')
.then(res => res.json()) // Tries to parse HTML as JSON
.then(data => console.log(data))
.catch(err => console.error(err)); // SyntaxError!
// Or plain text response
const response = "User not found";
JSON.parse(response); // SyntaxError!
// Check content type before parsing
fetch('/api/user')
.then(res => {
const contentType = res.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return res.json();
} else {
return res.text(); // Get as text instead
}
})
.then(data => console.log(data))
.catch(err => console.error(err));
// Or check if response is OK
fetch('/api/user')
.then(res => {
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
return res.json();
})
.then(data => console.log(data))
.catch(err => console.error(err));
// Use try-catch for manual parsing
function safeParse(str) {
try {
return JSON.parse(str);
} catch (error) {
console.error('Not valid JSON:', str);
return null;
}
}
// Trying to stringify and parse undefined
const obj = { name: 'John', age: undefined };
const jsonString = JSON.stringify(obj); // '{"name":"John"}' - age is omitted
console.log(jsonString);
// Function in object
const obj2 = {
name: 'John',
greet: function() { return 'Hello'; }
};
const jsonString2 = JSON.stringify(obj2); // '{"name":"John"}' - function omitted
// Use null instead of undefined
const obj = { name: 'John', age: null };
const jsonString = JSON.stringify(obj);
const parsed = JSON.parse(jsonString); // Works!
// Remove undefined values before stringifying
function cleanObject(obj) {
return Object.fromEntries(
Object.entries(obj).filter(([_, v]) => v !== undefined)
);
}
const obj2 = { name: 'John', age: undefined, city: 'NYC' };
const clean = cleanObject(obj2);
const jsonString2 = JSON.stringify(clean); // '{"name":"John","city":"NYC"}'
// Use replacer function
const obj3 = { name: 'John', age: undefined };
const jsonString3 = JSON.stringify(obj3, (key, value) => {
return value === undefined ? null : value;
});
JSON.parse() throws an error when the input string is not valid JSON. Common causes include single quotes instead of double quotes, trailing commas, parsing already-parsed objects, or trying to parse HTML/plain text.
Use double quotes for all strings, remove trailing commas, wrap in try-catch, check if data is already an object, and validate the JSON format before parsing.
JSON specification requires double quotes for strings. Single quotes are not valid JSON, even though they work in JavaScript objects. Always use double quotes in JSON.
Wrap JSON.parse() in a try-catch block, check the content type of API responses, validate the JSON format, and provide fallback values for parse errors.
Valid JSON uses double quotes for strings, no trailing commas, no undefined values, no functions, and no comments. Keys must be strings in double quotes.
Explore 500+ free tutorials across 20+ languages and frameworks.