An unexpected token error points to a parser failure, but not always to the change that caused it. Start with the JSON rules, then compare these ten broken and fixed examples with your input.

The rules

A document is a single value, usually an object or array, but any of the six types is allowed at the top level.

Object keys are strings in double quotes. Keys and values are separated by a colon, pairs by commas.

Array items are separated by commas.

Strings use double quotes only. Inside a string, backslash escapes are \" \\ \/ \b \f \n \r \t and \uXXXX. Raw control characters such as a literal tab are not allowed.

Numbers are decimal. Optional minus sign, no plus sign, no leading zeros except a bare zero, optional fraction, optional exponent. No hex, octal, NaN or Infinity.

The literals are exactly true, false and null in lowercase.

Whitespace between tokens is ignored. Whitespace means space, tab, line feed and carriage return only.

There are no comments.

RFC 8259 defines the syntax behind these checks. You can test an example in our JSON formatter before changing a production payload.

The ten errors

1. Trailing comma

{"a": 1, "b": 2,}     ✗
{"a": 1, "b": 2}      ✓

JavaScript and Python allow a comma after the last item.

JSON does not. A comma must separate two values; it cannot follow the final value.

2. Single quotes

{'name': 'Ada'}       ✗
{"name": "Ada"}       ✓

Python's print(dict) output looks like JSON but uses single quotes. Use json.dumps instead.

3. Unquoted keys

{name: "Ada"}         ✗
{"name": "Ada"}       ✓

Valid JavaScript object literal, invalid JSON.

4. Comments

{
// the user name
"name": "Ada"
}                     ✗

Some tools such as VS Code settings accept comments in files they call JSONC, but a standard parser will reject them.

Strip them out or use a JSON5 or JSONC parser.

5. Missing comma between items

{"a": 1 "b": 2}       ✗
{"a": 1, "b": 2}      ✓

Usually happens when pasting two fragments together. The error is reported at the start of the second key.

6. Unescaped quotes inside a string

{"quote": "She said "hi""}     ✗
{"quote": "She said \"hi\""}   ✓

7. Raw line breaks inside a string

{"text": "line one
line two"}            ✗
{"text": "line one\nline two"}   ✓

8. Wrong capitalisation of literals

{"ok": True, "v": NULL}      ✗
{"ok": true, "v": null}      ✓

Python writes True and None. JSON needs lowercase true and null.

9. Invalid numbers

{"n": 007}        ✗  leading zero
{"n": .5}         ✗  must be 0.5
{"n": +1}         ✗  no plus sign
{"n": NaN}        ✗  not a JSON value
{"n": 0x1F}       ✗  no hex

10. Undefined, functions and dates

{"cb": function() {}, "when": new Date()}   ✗

These are JavaScript values with no JSON form.

JSON.stringify silently drops undefined and functions and turns dates into strings, which is why the same object can round trip differently than you expect.

Bonus: duplicate keys

{"a": 1, "a": 2}

The grammar permits this, but RFC 8259 says object names should be unique.

Parsers handle duplicates differently; some retain only the last value. Do not rely on that behavior.

Reading the error message

Some parser messages include a character position or a line and column. Others contain no location.

A reported location can be later than the mistake, such as a missing comma on the previous line. Our JSON validator displays locations supplied by the parser or calculates the end position for unexpected end of input.

Without a position, the validator keeps the browser's original message. Once it parses, the JSON visualizer draws the structure so you can inspect where values belong.