toolgarden.xyz
中文
JSON syntax error fixunexpected tokenJSON repair

JSON Unexpected Token Error: How to Diagnose and Fix Common Syntax Errors

Trailing commas, single quotes, missing commas, truncated data, getting HTML instead of JSON. Locate the error in a fixed order and learn which problems can be auto-repaired and which need the data source.

ToolGarden tools prioritize browser-local processing, so files and text do not need to be uploaded to a server.

Published July 20, 2026Updated October 14, 202610 min readBy ToolGarden

The most frustrating thing about JSON parse errors is that the message tells you where parsing gave up, while the real cause is often earlier. This guide uses a fixed order, first rule out non-JSON, then syntax, then content, to locate Unexpected token style errors, and it separates what a tool can repair in one click from what you must chase back to the data source.

Step 1: confirm you actually have JSON

Before hunting character by character, look at the first and last characters. This step eliminates roughly half of the odd errors people see.

SymptomReal causeAction
First character is < (such as <!DOCTYPE)The server returned an HTML error, login or gateway pageCheck the HTTP status and Content-Type, not the JSON
First character is invisibleA BOM (byte order mark) at the startUse JSON Repair, which strips the BOM
Starts with jQuery123( or callback(JSONP, not JSONRemove the function wrapper before parsing
Whole value wrapped in quotes with \" insideJSON was serialized twice into a stringUnescape with JSON Escape, then format
Input is emptyThe request failed or the body is emptyCheck the request; the formatter shows no error for empty input

Step 2: read the error position correctly

When you paste invalid content into the JSON Formatter, you see the parser error. One detail: the page tries standard JSON first and falls back to JSON5, and when both fail the message shown comes from JSON5, in a form like "JSON5: invalid character ... at line:column". The browser console and Node.js use different wording, for example "Expected double-quoted property name in JSON at position 7". The position conventions differ but both point at the same area.

Rule of thumb: the reported position is not always the mistake itself. A missing comma is reported at the opening quote of the next key. Truncated data is reported at the end of the text. For bare words such as None, JSON5 sometimes points at the second letter. After reading an error, also inspect the few characters before it.

Step 3: work through real examples by category

1. Trailing commas and comments: auto-fixable

{"a": 1, "list": [1, 2, 3,],}   // two trailing commas

Standard JSON forbids trailing commas, and native parsing reports "Expected double-quoted property name". This is the most common hand-written config mistake. The JSON Repair page removes every trailing comma and leaves commas and slashes inside strings untouched. Comments are handled the same way: // and /* */ are removed.

2. Single quotes, bare keys, smart quotes: auto-fixable

{'name': 'Ada'}      // single quotes
{name: "Ada"}        // unquoted key
{“name”: “Ada”}      // smart quotes pasted from a document

The first two are accepted by the loose parser and written back with double quotes. Smart quotes (“ ”) usually arrive from Word or chat apps, and the repair page replaces them with straight quotes first. Note that the replacement is global: if a string value legitimately contains curly quotes, they become straight quotes, so double-check.

3. Python-style values: auto-fixable

{"ok": True, "owner": None, "debug": False}

Output copied from print(dict) is not JSON: True, False and None are capitalized, and single quotes are typical. The repair page converts them to true, false and null. The more robust habit is to use json.dumps in Python instead of copying print output.

4. Missing commas: not auto-fixed, repair by hand

{"a": 1 "b": 2}

Native error: "Expected , or } after property value". The JSON5 error is invalid character at the opening quote of the second key. A tool will not insert the comma because it cannot tell whether you forgot a comma or an entire key-value pair. Use the reported position, then add the comma after the previous value. In large files, jump to the reported line and column in your editor.

5. Truncated data: not auto-fixed, go back to the source

{"a": [1, 2

The message is "invalid end of input" at the end of the text. Common causes include a logging system limiting line length, copying a partial selection, a request cut off by a timeout, or a database column that was too short. Manually closing the brackets just yields valid-looking JSON with missing data, which is dangerous. Fetch the complete payload again.

6. Invalid escapes: understand the fallback before trusting the result

{"path": "C:\Users\bob"}

In standard JSON a backslash must be paired. \U is an illegal escape and native parsing reports "Bad escaped character". The catch: the loose JSON5 fallback accepts it, treats \U as a plain U and produces CUsers, while \b becomes a backspace control character. The formatter says success, yet the data has been quietly altered. Write backslashes in paths as \\ and inspect string values after formatting.

7. Real newlines and tabs inside strings: must be escaped

String values cannot contain raw line breaks or tab characters. The native error is "Bad control character in string literal". Multi-line text must be written with \n. Long strings copied out of logs hit this constantly.

8. undefined, NaN, Infinity: not JSON

{"a": undefined} cannot be parsed in any mode. NaN and Infinity are rejected by native JSON; the loose fallback reads them, but writing standard JSON turns them into null, so the original numeric information is gone. Handle these at the producer: replace them with null or a string before serializing, and document the meaning.

What can be auto-fixed and what cannot: one table

Error typeJSON Repair pageNotes
Comments (// and /* */)YesText inside strings is kept
Trailing commasYesOnly before } or ]
Single quotes, bare keysYesVia the loose parser, written with double quotes
Smart quotes, BOMYesGlobal replacement, verify the result
True / False / NoneYesReplaced by word boundary, so the same words inside strings are replaced too; verify
Missing comma or colonNoAuthor intent cannot be inferred
Truncation, unclosed bracketsNoCompleting would be inventing data
undefinedNoNot a legal value, fix at the producer
Schema mismatchNot a syntax issueUse the JSON Schema Validator for missing fields and wrong types

Worked example: a config that looks like it has one error

This config has several problems, and you meet them one at a time:

{
  // service config
  'name': 'billing',
  "retries": 3,
  "debug": False,
  "ports": [8080, 8081,],
  "owner": None
}

After one repair pass the comment is gone, single quotes become double quotes, False and None become false and null, and the trailing comma is removed, giving valid JSON. If you only format without repairing, False makes parsing fail on line 5, and only after fixing it does the None problem surface, the classic one-error-at-a-time experience. For text of unknown origin, repair first and format second to see the complete picture at once.

Step 4: syntax is fine but the content is still wrong

Once syntax is valid, the second most common problem is content that does not match expectations: missing fields, changed types, numbers that became strings. Stop looking at syntax and check with the JSON Schema Validator, which lists each mismatch as a path and a reason, for example $.items[0].price should be a number. For integers beyond 2 to the power of 53, JavaScript loses precision, so send IDs as strings. Many apparent syntax errors are really data problems: the same endpoint returns different shapes in different environments, for example an array in staging but null in production when there is no data. Formatting both responses and diffing them is often faster than staring at the error message.

Prevent it at the source

Fixing the same class of error repeatedly means the problem is on the producer side. These habits stop most syntax errors where the data is created.

ScenarioWrong approachRight approach
Python emitting JSONCopying the result of print(dict)Use json.dumps(obj, ensure_ascii=False) to get real double quotes and true / null
JavaScript building JSONString concatenation, which breaks when a value contains a quoteUse JSON.stringify and let it handle escaping
Hand-written configWriting from memory with no validationEnable JSON syntax checking in the editor and parse the file in CI before merging
LoggingTruncating the whole log line by lengthSerialize completely first, or truncate an oversized field rather than the whole JSON
HTTP APIsReturning an HTML page on error while Content-Type still says JSONReturn JSON errors with the right status code and Content-Type

Two more habits are worth building. First, have the consumer check Content-Type and the first character before parsing, and report "received HTML" when it sees <, rather than throwing an obscure parse error. Second, when parsing fails, log a few dozen characters around the error position instead of the whole response, which helps debugging and also avoids writing sensitive data into logs wholesale.

A one-time checklist

  1. Does the response start with { or [, and is Content-Type JSON?
  2. Are there unescaped newlines, tabs or backslashes inside strings?
  3. Are there trailing commas, comments, single quotes or Python-style True / None?
  4. Are brackets closed in pairs, and is the end of the text truncated?
  5. Once syntax passes, do fields and types match the agreed contract?

When not to rely on online repair

  • Data with sensitive information when you are unsure of page behavior: redact first, or process it locally on the command line with jq.
  • Audit data that must be byte-for-byte exact: any automatic repair can change content, so re-export from the source.
  • Truncated large files: closing brackets is meaningless, so find out why the upstream truncated it.
  • Configs that must keep comments: repair output is standard JSON and comments are removed, so save to a new file instead of overwriting the original.

Frequently asked questions

Q.What does Unexpected token < in JSON at position 0 mean?

The parser hit < as the very first character, so you almost certainly received HTML (an error page, login page or gateway page) instead of JSON. Check the request URL, status code and Content-Type instead of editing the JSON.

Q.Why does JSON not allow trailing commas and comments?

The JSON specification is deliberately minimal: no comments and no comma after the last element. JSONC and JSON5 allow these. When a strict parser must consume the data, convert it to standard JSON with the JSON Repair page first.

Q.The formatter reported success, so why did my string content change?

After standard parsing fails the page falls back to the looser JSON5 parser, which tolerates some invalid escapes. \U is read as a plain character, so C:\Users becomes CUsers. When backslash paths are involved, check the formatted string values and use \\ at the source.

Q.Why can a missing comma not be added automatically?

A missing comma can mean you forgot the comma or forgot a whole key-value pair, and a tool cannot know which. A wrong guess yields data that looks correct but is not, which is worse than an error, so a human must confirm.

Q.Can I just close the brackets on truncated data?

Syntactically yes, but the missing fields are already lost, so the data is wrong for the business. Find the cause of the truncation (log length limit, timeout, incomplete copy) and fetch the data again.

Q.Why is there no error when the same key appears twice?

Standard parsers allow duplicate keys and keep the last value without complaint. If you suspect an overwritten setting, search the raw text for repeated key names or use a parser that detects duplicates.