Skip to content
Debugging

JSON Parse Error: Causes and How to Fix It Fast

·9 min read

You call JSON.parse(). Your app crashes. The console screams: SyntaxError: Unexpected token < in JSON at position 0.

If you have ever stared at that error message wondering what on earth went wrong - you are not alone. JSON parse errors are one of the most common runtime errors in JavaScript, and they show up in every environment. Browser apps. Node.js servers. Mobile apps. Build tools. Everywhere.

The good news? There are really only a handful of things that cause them. Once you know what to look for, you can fix most JSON parse errors in under a minute.

Let's break down the top five causes - and exactly how to fix each one.

What "SyntaxError: Unexpected Token" Actually Means

When you call JSON.parse(), the parser reads your string character by character. It expects the string to follow strict JSON syntax - double-quoted keys, no trailing commas, no comments, no single quotes.

The moment it hits a character that does not belong, it throws a SyntaxError. The "unexpected token" is simply the first character that broke the rules. The "at position" number tells you exactly where in the string the parser gave up.

So Unexpected token < at position 0 means the very first character is a < - which is HTML, not JSON. And Unexpected end of JSON input means the parser reached the end of the string before finding a complete JSON structure.

That context is everything. Once you understand the pattern, you can diagnose the problem in seconds.

Top 5 Causes of JSON Parse Errors

1. Unexpected Token at Position 0 - HTML Instead of JSON

This is the number one cause of JSON parse errors in web applications. You make a fetch() call expecting JSON back, but the server returns an HTML error page instead. A 404 page. A login redirect. A 500 server error rendered as HTML.

Your code does not check the response status. It just calls response.json(). The parser sees <!DOCTYPE html> and immediately throws Unexpected token < at position 0.

// This will fail if the server returns HTML
const response = await fetch("/api/users");
const data = await response.json(); // SyntaxError!

// Fix: always check the response status first
const response = await fetch("/api/users");
if (!response.ok) {
  throw new Error(`Server returned ${response.status}: ${response.statusText}`);
}
const data = await response.json();

How to debug it:Open your browser's Network tab. Click on the request. Look at the Response tab. If you see HTML instead of JSON, the problem is not your parsing code - it is your API endpoint or your URL. Check the URL for typos. Check that the server is actually running. Check that you are not being redirected to a login page.

2. Trailing Commas

JavaScript allows trailing commas. JSON does not. This is one of the most common mistakes developers make when writing JSON by hand, and it is covered in depth in our guide to fixing trailing commas in JSON.

// WRONG - trailing commas after last items
{
  "name": "Alex",
  "roles": ["admin", "editor",],
  "active": true,
}

// RIGHT - no trailing commas
{
  "name": "Alex",
  "roles": ["admin", "editor"],
  "active": true
}

How to debug it: Look at the position number in the error message. Go to that character in your JSON string. Nine times out of ten, you will find a comma right before a closing bracket or brace. Remove it.

3. Single Quotes Instead of Double Quotes

JSON requires double quotes for all strings and keys. No exceptions. Single quotes and backticks are not valid JSON - even though JavaScript accepts them just fine.

// WRONG - single quotes
{
  'name': 'Alex',
  'email': 'alex@example.com'
}

// RIGHT - double quotes only
{
  "name": "Alex",
  "email": "alex@example.com"
}

This happens constantly when developers copy Python dictionary output or hand-write JSON in a text editor. If you are working with Python, always use json.dumps() to produce valid JSON rather than copying the repr() output of a dictionary.

How to debug it: Search your JSON string for single quotes. Replace every ' with ". If you are doing this programmatically, be careful not to replace single quotes that appear inside double-quoted string values.

4. Undefined and NaN Values

undefined, NaN, and Infinity are JavaScript concepts. They do not exist in JSON. If you try to parse a string containing any of these, you will get a syntax error.

// WRONG - these are not valid JSON values
{
  "name": "Alex",
  "age": undefined,
  "score": NaN,
  "limit": Infinity
}

// RIGHT - use null for missing values, numbers for numeric values
{
  "name": "Alex",
  "age": null,
  "score": 0,
  "limit": 999999
}

The sneaky part is that JSON.stringify() handles these silently. undefined values get dropped entirely. NaN and Infinity get converted to null. So the JSON your server sends might look fine - until you manually construct a JSON string without using JSON.stringify() and include these values.

How to debug it: Search your raw JSON string for undefined, NaN, and Infinity. Replace them with null or an appropriate default value. For a deeper dive, see our guide to common JSON errors.

5. Empty Response Body

This one trips people up because there is no visible error in the response - there is just nothing there. Your API returns a 204 No Content, or an empty 200 response. You call response.json() on an empty string and get SyntaxError: Unexpected end of JSON input.

// This fails on empty responses
const data = await response.json();

// Fix: check for content before parsing
const text = await response.text();
const data = text ? JSON.parse(text) : null;

How to debug it: Log response.status and response.headers.get("content-length"). If the content length is 0 or the status is 204, do not try to parse the body as JSON. Handle the empty case explicitly.

How to Wrap JSON.parse in Try/Catch Properly

Every call to JSON.parse()should be wrapped in error handling. No exceptions. Even if you are "sure" the input is valid, treat parsing as an operation that can fail - because in production, it will.

function safeJsonParse(text) {
  try {
    return { data: JSON.parse(text), error: null };
  } catch (err) {
    return { data: null, error: err.message };
  }
}

// Usage
const { data, error } = safeJsonParse(responseText);
if (error) {
  console.error("Invalid JSON:", error);
  // Handle the error - show a message, use a fallback, retry
} else {
  // Safe to use data
  console.log(data);
}

This pattern gives you a clean way to handle failures without letting your app crash. You get the parsed data when it works, and a descriptive error message when it does not. No unhandled exceptions. No silent failures.

For more patterns like this, check out our complete guide to JSON in JavaScript.

How to Check If a String Is Valid JSON Before Parsing

Sometimes you want to validate a string without actually using the parsed result. Maybe you are building a form that accepts JSON input. Maybe you are logging payloads and want to flag invalid ones.

function isValidJson(text) {
  try {
    JSON.parse(text);
    return true;
  } catch {
    return false;
  }
}

// Examples
isValidJson('{"name": "Alex"}');     // true
isValidJson("{'name': 'Alex'}");     // false - single quotes
isValidJson('{"name": "Alex",}');    // false - trailing comma
isValidJson("");                      // false - empty string

Yes, this still uses try/catch under the hood. There is no built-in JSON.validate() method in JavaScript - the only reliable way to check if a string is valid JSON is to try parsing it. The performance cost is negligible for any reasonable input size.

Use an Online JSON Validator to Find the Error Instantly

When you are staring at a wall of minified JSON and the error says "position 4287" - do not count characters. Paste it into a validator.

A good JSON validator will format your JSON, highlight the exact line where the syntax breaks, and tell you what went wrong in plain language. What takes five minutes of manual debugging takes two seconds with the right tool.

This is especially useful for the tricky errors - a single quote hiding in a 200-line config file, a trailing comma buried three levels deep in a nested object, or an invisible Unicode character that looks like a normal space but is not.

You can paste any broken JSON into JSON Prettifier and immediately see where the error is. No signup, no install, no fuss.

Quick Reference: JSON Parse Error Cheat Sheet

Every one of these has a straightforward fix once you know what to look for. And if you want the full list of JSON syntax gotchas, read our complete guide to common JSON errors.

Fix Your JSON Parse Error Right Now

Paste your broken JSON into our validator. It will pinpoint the exact character causing the error and show you how to fix it - in seconds.

Open JSON Prettifier