TryBugHunt

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON in JavaScript means you called response.json() on an API response that returned an HTML webpage (such as a 404 or 500 error page) instead of JSON data.

JavaScriptPattern: Logic errors

How do I fix SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON?

To fix SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON in JavaScript, locate the line causing the error and check the values right before it runs. Most occurrences happen because of api route returned a 404 or 500 html page. Apply a defensive check or safe fallback, make sure collections or objects exist before access, and verify return values from upstream functions.

1. Inspect bounds & typesPrint or inspect collection sizes and verify variables are not empty or None/undefined.
2. Guard with safe accessUse optional chaining (?.), dictionary get(), or guard conditions before dereferencing.
3. Trace upstream originsFind where the value was instantiated or returned rather than only patching the symptom.

What does SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON mean?

response.json() expects valid JSON starting with { or [. When an endpoint 404s, crashes, or redirects to a login page, the server returns an HTML document starting with <!DOCTYPE html>. JSON.parse hits the < bracket and crashes.

Why does SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON happen?

1. API route returned a 404 or 500 HTML page

res.json() is called unconditionally without checking res.ok.

Breaks

const res = await fetch("/api/users");
const data = await res.json();

Works

const res = await fetch("/api/users");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();

2. Authentication redirect returned HTML login page

An unauthenticated API request gets redirected by middleware to /login.

Breaks

const res = await fetch("/api/protected");
const data = await res.json();

Works

const res = await fetch("/api/protected");
const contentType = res.headers.get("content-type");
if (!contentType?.includes("application/json")) throw new Error("Expected JSON");
const data = await res.json();

3. Wrong API path in Next.js or Vite

Requesting a missing API path falls through to the single-page app HTML index.

Breaks

fetch("/api/typo-route");

Works

fetch("/api/correct-route");

How to find it in your own code

Always check `if (!response.ok)` before parsing the response body. If an error occurs, inspect `await response.text()` to see the actual HTML response from the server.

Try it: fix this bug

easy

sortNumbers([10, 2, 30]) returns [10, 2, 30].

function sortNumbers(arr) {
    return arr.sort();
}
Open with hintsRuns in your browser. No account needed.

More challenges with this error

Each of these challenges runs into this error or pattern. Find the bug and fix it in your browser โ€” no install, no account needed.

Still not sure why yours breaks?

Paste it into the visualizer and watch it run line by line, with every variable at every step. Free, and it runs in your browser.

Related error guides

View all logic errors โ†’