Skip to content
Tools

Unexpected Token in JSON at Position 0 (and Every Other Position): What It Means

· 7 min read

"Unexpected token" means JSON.parse reached a character that JSON's grammar does not allow at that point, and the position is the zero-based index where it gave up. At position 0 the input is not JSON at all (usually HTML, undefined or an object that was already parsed); at a later position it is almost always a trailing comma, a single quote, a comment or a missing comma just before the reported spot. Paste the text into the JSON validator to get the line, column and a plain-English reason.

The wording you see depends on the engine and its version. Chrome and Node.js changed their messages in 2023 (V8 10.9 era, Chrome 110+, Node 20+), so a Stack Overflow answer about Unexpected token } in JSON at position 42 describes the same bug as today's Unexpected token '}', ..."a": 1,}" is not valid JSON. This page maps every variant to its cause.

Minimal reproduction

One trailing comma, three different messages. Positions count from 0; Firefox columns count from 1.
JSON.parse('{"a": 1,}');
// Chrome / Node 20+: SyntaxError: Expected double-quoted property name in JSON at position 8
// Chrome / Node 18:  SyntaxError: Unexpected token } in JSON at position 8
// Firefox:           SyntaxError: JSON.parse: expected double-quoted property name at line 1 column 9 of the JSON data

JSON.parse("[1, 2,]");
// Chrome / Node 20+: SyntaxError: Unexpected token ']', "[1, 2,]" is not valid JSON

Read the position first

The number is a character offset into the string you passed, starting at 0. Firefox reports a line and a column starting at 1, and recent Chrome and Node builds append (line 1 column 9) to the position. Two rules save most of the debugging time:

  • Position 0 or 1: the text never was JSON. Log typeof value and the first 200 characters before you look at the JSON itself.
  • Any later position: the real mistake is usually just before it. A trailing comma is reported at the closing bracket after it; a missing comma is reported at the start of the next value.

Causes, most common first

Ranked by how often each cause appears in support questions and pasted inputs; treat the order as a rule of thumb, not a statistic.
#CauseTypical messageFix
1HTML instead of JSON (error page, login redirect, dev-server fallback)Unexpected token '<', "<!DOCTYPE "... is not valid JSONCheck response.ok and Content-Type; see the DOCTYPE guide.
2Parsing something that is already an object, or undefinedUnexpected token 'o', "[object Obj"... is not valid JSON / "undefined" is not valid JSONDo not parse twice; see token o and undefined.
3Trailing commaExpected double-quoted property name or Unexpected token ']'Delete the comma before } or ].
4Single quotes or unquoted keysExpected property name or '}'Use double quotes on every key and string.
5Comments (//, /* */)Unexpected token '/'Strip them, or parse as JSONC.
6Two values back to back, or junk after the valueUnexpected non-whitespace character after JSONParse one value at a time or wrap them in an array.
7Raw tab or newline inside a stringBad control character in string literalEscape as \t or \n.
8Byte order mark or other invisible character at the startUnexpected token at position 0 with an invisible or blank-looking tokenStrip the BOM before parsing.

Each message, explained

Unexpected token < in JSON at position 0

This is the older Chrome and Node (18 and earlier) wording; Chrome 110+ and Node 20+ say Unexpected token '<', "<!DOCTYPE "... is not valid JSON. Any token at position 0 means the first character is wrong. < is HTML, u is undefined, o comes from [object Object] (position 1), and an apparently empty token is usually a byte order mark.

Unexpected token 'x', "..." is not valid JSON

Current V8 quotes the offending character and a short excerpt of your input. The excerpt is the useful part: "<!DOCTYPE "... tells you it is HTML, ..."a": 1,}" points at a trailing comma. When the whole input is short, V8 prints it in full; when the input is just a word, the message becomes "undefined" is not valid JSON with no token at all.

Expected property name or '}' in JSON at position 1

Inside {, the parser needs a double-quoted key or a closing brace. Position 1 almost always means the key uses single quotes or none: {'a': 1} or {a: 1}. Firefox reports this as JSON.parse: expected property name or '}' at line 1 column 2 of the JSON data. If the text came from Python print(dict), read Python dict to JSON with single quotes.

Expected double-quoted property name in JSON

V8 and Firefox both use this wording when a comma inside an object is followed by }: the comma promised another key and none came. Remove the trailing comma. The JSON fixer removes every trailing comma at once and shows a diff.

Unexpected non-whitespace character after JSON at position

The parser read one complete value and then found more text. Common sources are two objects pasted together ({"a":1}{"b":2}), NDJSON lines parsed as a single document, a stray } left by an edit, or a server that appends debug output after the body. Firefox says JSON.parse: unexpected non-whitespace character after JSON data. For line-delimited files, split on newlines and parse each line; see what NDJSON is.

Unterminated string in JSON at position

A string opened with " and the input ended before the closing quote. Either the text was cut off (a truncated response or a size-limited log line) or an inner quote was not escaped, so the string ended early and a later quote opened a new one. Write inner quotes as \". If the text is truncated, see Unexpected end of JSON input.

Bad control character in string literal in JSON

Characters below U+0020, such as a literal tab or line break, must be escaped inside strings. This appears when a multi-line value is pasted into JSON by hand or a template inserts raw text. Replace the raw characters with \n, \r or \t, or better, build the JSON with JSON.stringify so escaping is automatic.

Bad escaped character in JSON

Only \", \\, \/, \b, \f, \n, \r, \t and \uXXXX are valid escapes. Windows paths are the usual culprit: "C:\data" is invalid because \d is not an escape. Double the backslash or use forward slashes.

JSON.parse: unexpected character at line 1 column 1 of the JSON data

This is Firefox's generic message for a first character that cannot start a JSON value; it is the equivalent of Chrome's position-0 errors. In practice it means HTML, undefined, or plain text. Firefox reports the same message at column 2 for [object Object].

JSON Parse error: Unrecognized token

Safari and other JavaScriptCore runtimes (including Bun) use the JSON Parse error: prefix, for example JSON Parse error: Unrecognized token '<' for HTML and JSON Parse error: Unexpected identifier "undefined" for undefined. They do not include a position, so use the validator to locate the problem.

The invisible character at position 0

If the text looks perfect but fails at position 0, the file probably starts with a UTF-8 byte order mark (U+FEFF), which Windows editors and some exports add. JSON.parse does not skip it. Strip it before parsing:

const clean = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
const data = JSON.parse(clean);

Check whether a string is valid JSON

JSON.parse throws a SyntaxError on invalid input, so wrap it and keep the raw text for the log. Logging the first characters and the type is what turns a vague error into an obvious one:

function tryParseJson(value) {
  if (typeof value !== "string") {
    return { ok: false, error: "Expected a string, got " + typeof value };
  }
  try {
    return { ok: true, data: JSON.parse(value) };
  } catch (err) {
    return { ok: false, error: err.message, head: value.slice(0, 120) };
  }
}

Do not "fix" the error by catching it and returning an empty object. That hides the server bug or the bad input that caused it.

Fix it in three steps

  1. Log typeof value and the first 200 characters of the input. Position-0 errors are solved here.
  2. Paste the text into the validator to get the exact line and column with a readable explanation.
  3. For syntax mistakes (commas, quotes, comments, Python literals), run the JSON fixer and review its diff. For output from ChatGPT or another model, use Fix LLM JSON, which also strips Markdown fences and prose.

For a one-line summary of every JSON error family, the common JSON errors hub links to the detailed guide for each.

FAQ

What does "Unexpected token in JSON at position 0" mean?

The very first character is not valid JSON, so the input was never JSON. It is usually an HTML page (<), the value undefined (u), or a byte order mark. Log the raw text before parsing to see what you actually received.

Why did my error message change from "Unexpected token } in JSON" to "is not valid JSON"?

V8 rewrote its JSON error messages around Chrome 110 and Node 20. New messages quote the token and an excerpt of the input, and some errors got specific names such as Expected double-quoted property name. The causes are the same.

Is the position in the error 0-based or 1-based?

Chrome and Node positions are 0-based character offsets. Firefox and the validator report 1-based line and column numbers, so position 8 in Chrome is column 9 on a single-line input.

What does "Unexpected non-whitespace character after JSON" mean?

The parser finished one complete JSON value and found more text after it, for example two objects back to back or NDJSON parsed as one document. Remove the extra text or parse each value separately.

How do I find which line has the unexpected token?

Paste the text into a JSON validator that reports line and column. In code, convert the position yourself: count the newlines in text.slice(0, position).

More JSON guides