You're shipping what feels like a perfectly normal feature. An API response comes back, you throw it at JSON.parse(), and suddenly the whole app is down with a SyntaxError: Unexpected token staring you in the face. I've been there more times than I'd like to admit. The worst part isn't the error itself, it's that the error message tells you almost nothing useful. "Unexpected token u in JSON at position 0" doesn't exactly point you to the problem.

The good news is that broken JSON almost always fails for one of a handful of very predictable reasons. Once you know what to look for, you can usually spot the culprit in under ten seconds. Here's how.

Why JSON.parse() Fails (and Why the Error Is Useless)

The JavaScript runtime parses JSON with zero tolerance. One missing quote, one trailing comma, one stray character, and the whole thing throws. The problem is that the native error message just tells you the character it choked on and its position in the string. That position is often somewhere deep in a 40,000-character API blob, which isn't exactly helpful when you're under pressure.

The most common culprits I see are:

  • Trailing commas. This is the number one offender. JavaScript objects and arrays let you leave a comma after the last item. JSON does not. Copy-pasting JS object syntax into a JSON context will bite you every time.
  • Single quotes instead of double quotes. JSON requires double quotes. Property names, string values, all of it. If you hand-wrote or templated any part of that JSON, check every single quote character.
  • Undefined or null values coming in as the literal string "undefined". If JSON.parse() says "Unexpected token u at position 0," you're almost certainly passing it the string "undefined" because the variable you tried to parse was never set.
  • HTML or an error page where you expected JSON. If an API returns a 500 error page or a redirect to a login screen, you get HTML. The < at the start of <!DOCTYPE is very much not valid JSON.
  • Control characters and encoding issues. Raw newlines, tabs embedded in a string literal without escaping, or a BOM character at the start of a file will all silently corrupt what looks like valid JSON.

The 10-Second Debugging Workflow

Before you touch a line of code, grab the raw string that's failing and paste it somewhere you can actually see it. That's step one, and it's the step most people skip because they assume they can read it in a console log. You can't. Console logs collapse long strings, truncate arrays, and don't show you invisible characters at all.

Step 1: Validate the raw string, not your assumption of it

Log the raw value before parsing it. In practice this means something like console.log(typeof responseText, responseText) right before the JSON.parse() call. You want to confirm it's actually a string and that it starts with { or [. If it starts with anything else, you already know where to look.

Step 2: Check for undefined coming in

If the error is "Unexpected token u at position 0," do this immediately. Check that the variable you're parsing is actually set. A common pattern is storing something in localStorage, reading it back, and parsing it, but forgetting that on first load there's nothing there yet, so localStorage.getItem('myKey') returns null, and JSON.parse(null) actually works, but JSON.parse(undefined) throws. Check your fallbacks.

Step 3: Format it to spot the structure problem

If the string itself looks like JSON but still won't parse, the issue is almost always structural. A good formatter will re-indent the JSON and highlight the exact line where the structure breaks. You'll see the mismatched bracket or the trailing comma immediately instead of hunting through raw text.

The error message tells you where the parser gave up. The actual bug is almost always one character before that.
🔧
Try It Yourself
JSON Formatter
Paste your broken JSON and instantly see it formatted, validated, and highlighted so the syntax error jumps out immediately.

Writing Code That Doesn't Crash on Bad JSON

Debugging the immediate error is one thing. Making sure it doesn't take down your app next time is another. There's a pattern I use everywhere now that takes about 30 seconds to write and saves a lot of pain later.

Wrap every JSON.parse() call in a try/catch and return a sensible default. Something like this:

function safeParse(str, fallback = null) {
  try {
    return JSON.parse(str);
  } catch {
    return fallback;
  }
}

This is not fancy, but it means a malformed API response gives you null instead of an uncaught exception. You can then handle null gracefully in your UI rather than watching the whole component tree blow up.

Validating before you parse

If you're dealing with user-submitted JSON or JSON from a source you don't fully control, it makes sense to validate the structure after parsing, not just catch the parse error. JSON Schema is the proper tool for that, but for quick checks, just assert the shape you expect: check that the result is an object, that required fields exist, that arrays are actually arrays. Don't assume the structure just because the parse succeeded.

What about JSON.stringify() on the other end?

Worth mentioning: if you're generating JSON rather than consuming it, JSON.stringify() will silently drop properties with undefined values and will throw on circular references. If the JSON you're producing is what you're later parsing, both of these can create confusing bugs where the structure you serialized doesn't match what you get back. Always log the stringified output once during development just to confirm it matches your expectations.

📌 Key Takeaways
  • The native JSON.parse() error message tells you where the parser stopped, not where the bug is. Look one step earlier.
  • "Unexpected token u at position 0" almost always means you're trying to parse the literal string "undefined" because a variable wasn't set.
  • Trailing commas and single quotes are the two most common structural errors, especially when copying from JavaScript into JSON contexts.
  • Paste your failing JSON into a formatter before doing anything else. A structured view makes the problem obvious in seconds.
  • Wrap every JSON.parse() in a try/catch with a fallback return value so one bad response can't crash your whole app.

The Fastest Path From "It's Broken" to "It's Fixed"

When JSON.parse() blows up in production or during development, here's the exact sequence to run through:

  1. Log the raw value and its type before the parse call. Confirm it's a string that starts with { or [.
  2. Check for "undefined" at position 0. If so, trace back to where that variable gets set and add a null check or default value.
  3. Check for HTML. If the string starts with <, your API returned an error page or redirect. Fix the API call or add error status checking before you even attempt to parse.
  4. Paste it into a JSON formatter. Let the formatter highlight the exact line with the syntax problem. Fix the trailing comma, mismatched bracket, or quote issue it finds.
  5. Wrap the parse call in a try/catch before you close the file, so this can't take down your app again even if the same edge case slips through later.

It sounds like a lot of steps written out, but in practice you'll usually find the problem at step 1 or step 3 and be done in under a minute. The formatter in particular is the shortcut most people don't know to reach for, and it's the fastest way to turn a wall of unreadable JSON into something that immediately shows you the problem.