Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

Why is my JSON invalid? — common syntax errors and how to fix them

On this page
  1. JSON’s strict rules in one screen
  2. Trailing commas, single quotes, comments
  3. Unescaped strings and bad numbers
  4. Using the validator to find the line
  5. Format vs minify vs validate — which tool when

Your JSON looks fine. The parser disagrees.

Most “invalid JSON” is not a mystery. It is a JavaScript object, a Python dict, or a VS Code settings file wearing JSON’s clothes. Strict JSON — RFC 8259 — rejects trailing commas, single quotes, comments, unquoted keys, and a handful of number shapes every neighboring language accepts.

This page is the short list of those rules, with before/after fixes. Paste the broken text into the validator to jump to the error. Pretty-print the result in the formatter. Both run in your browser. Nothing is uploaded. There is no account.

JSON’s strict rules in one screen

JSON is six value types and a small set of punctuation. That is the entire language.

RuleAllowedRejected
Strings and keysDouble quotes "name"'name', unquoted name
Trailing commasNo{ "a": 1, } and [1, 2,]
CommentsNo//, /* */, #
Numbers-12, 3.14, 1.5e10012, 1., .5, NaN, Infinity
Extra valuestrue, false, nullundefined, None, Nil
RootAny single JSON valueTwo values side by side, or a whole NDJSON file as one document

An object is { ... }. An array is [ ... ]. A document is exactly one value. Keys are always strings. Whitespace between tokens is fine; a raw newline inside a string is not.

If you remember one thing: JSON is not JavaScript. JSON.parse is stricter than an object literal. The same is true of Python’s json.loads versus a dict you typed in a REPL. For the six types and the rest of the gotchas, see What is JSON?.

Trailing commas, single quotes, comments

These three cause most of the red status lines. They are legal in neighboring formats. They are not legal here.

Trailing comma. Easy to leave when you delete the last item, or when a JavaScript pretty-printer adds one.

Before:

{
  "name": "Ada",
  "role": "admin",
}

After:

{
  "name": "Ada",
  "role": "admin"
}

Same rule in arrays: [1, 2, 3,] is invalid. Drop the last comma. JSONC and JSON5 allow trailing commas; strict JSON does not. The validator will usually say Unexpected token } or Unexpected token ] at the comma’s neighbor.

Single quotes. Python prints dicts with single quotes. JavaScript accepts them in source. JSON does not.

Before:

{ 'name': 'Ada', 'ok': true }

After:

{ "name": "Ada", "ok": true }

If the string itself contains a double quote, escape it (\") — do not switch the outer quotes to single.

Comments. tsconfig.json and VS Code settings are JSONC. Real JSON has no comment syntax.

Before:

{
  // production host
  "host": "api.example.com"
}

After:

{
  "host": "api.example.com"
}

Move the note to a "_comment" field if you must keep it in-band, or keep a sidecar README. Do not ship // to a strict parser.

Unescaped strings and bad numbers

Once quotes and commas are clean, the next failures are almost always a string that was not escaped, or a number JSON does not have.

Quotes and backslashes inside strings. A raw " ends the string. A single \ starts an escape; if the next character is not a valid escape, the parse dies.

Before:

{ "path": "C:\temp\new", "note": "She said "ship it"" }

After:

{ "path": "C:\\temp\\new", "note": "She said \"ship it\"" }

Windows paths are the classic trap: \t is a tab and \n is a newline. Double every backslash, or use forward slashes. Newlines inside a string must be written \n, not as an actual line break. Bare keys ({ name: "Ada" }) fail the same way as single quotes — quote them.

Bad numbers. JSON numbers cannot have a leading zero (except 0 itself), a trailing decimal point, or a leading decimal point. They cannot be NaN or Infinity.

Before:

{ "zip": 02115, "score": NaN, "ratio": .5 }

After:

{ "zip": "02115", "score": null, "ratio": 0.5 }

Keep leading-zero IDs as strings. Encode missing math as null (or a documented sentinel string), not NaN.

Using the validator to find the line

You do not have to hunt by eye.

  1. Open the JSON validator.
  2. Paste the document. The status line under the editor is the answer: ✓ Valid JSON or ✗ Invalid JSON plus the browser’s JSON.parse message.
  3. Read the position. Messages look like Unexpected token } in JSON at position 47 or Expected double-quoted property name. The number is a character offset from the start of the paste, not always a line number. Jump there in any editor, or count from the top of a short snippet.
  4. Fix that token. Paste again. Repeat until the status is green.
  5. When it is valid, send the same text through the formatter if you want indentation you can read.

Typical mappings:

Status lineFix
Unexpected token } / ]Trailing comma
Expected double-quoted property nameSingle-quoted or bare key
Unterminated stringMissing quote, or a raw newline in a string
Unexpected numberLeading zero
Unexpected end of JSON inputMissing } or ]
Unexpected non-whitespace characterA second value after the first, or a comment

The paste never leaves your machine. The page uses the browser’s own JSON.parse. Open DevTools → Network if you want to confirm there is no upload. No signup.

Open the validator →

Format vs minify vs validate — which tool when

Same engine, three jobs.

You wantUse
Is this parseable, and where does it break?Validator
Readable indent, sorted keys, a copy buttonFormatter
Smallest valid JSON for a URL, log line, or data-* attributeMinifier
A YAML file humans will editJSON → YAML

Validate first. Formatting and minifying both call JSON.parse and then JSON.stringify — they cannot pretty-print a document that is not JSON yet. If the formatter’s status is red, you are still in the syntax-error loop above.

Once it is valid:

None of these tools check a schema. “Valid JSON” means the text parses. It does not mean the object has the fields your API promised. For that you want JSON Schema or a runtime checker in your language.

If the file is meant for humans to edit — comments, less punctuation — JSON may be the wrong format. See JSON vs YAML.