Cadmeo

JSON Validator

Invalid: line 3, column 35

There is a trailing comma before the closing bracket. JSON does not allow one, unlike JavaScript.

Where it fails
  "fields": ["maths", "computing",],
                                  ^
Parser message

Unexpected token ']', ..."omputing",], }" is not valid JSON

The validator answers one question: if your JSON will not parse, where and why. It reports the line and column, prints the offending line with a caret under the exact position, and translates the parser's message into the mistake that actually caused it.

How it works

The document is handed to the same JSON parser your code uses. When it throws, the error carries a character offset into the string, which is useless on its own in a 4,000-line document, so it is converted to a line and column and the line is printed with a marker.

Parser messages are written for implementers, not for the person holding the broken file. "Unexpected token }" is technically correct and points at the brace rather than at the trailing comma before it that caused the problem. Where the message and surrounding text identify a known cause, the plain-language explanation is shown instead.

  • A trailing comma before a closing bracket or brace, valid JavaScript, invalid JSON.
  • Single-quoted strings, which JSON does not allow at all.
  • Unquoted object keys, again valid JavaScript and not JSON.
  • Python's True, False and None, which JSON spells true, false and null in lowercase.
  • A truncated document, where the text ends before a bracket or quote is closed.
  • Content after the end of the document, which usually means two values were concatenated without an enclosing array.

Valid is not the same as correct. A document that parses cleanly may still have the wrong keys, the wrong types or missing fields, checking that needs a schema, which is a different kind of validation entirely.

Examples

A trailing comma

JSON

{"fields": ["maths", "computing",],}

Result

Invalid at line 1, column 34: trailing comma before the closing bracket

The comma after "computing" is the problem; the parser fails at the bracket after it. Both the array and the object here have a trailing comma, and the array is reached first.

Single quotes

JSON

{'name': 'Ada'}

Result

Flagged: JSON strings must use double quotes

This is the most common paste-from-JavaScript error. Object literals in JS allow single quotes; JSON never does.

A Python dictionary

JSON

{"active": True}

Result

Flagged: JSON spells the literals in lowercase

Python prints True, False and None. JSON requires true, false and null. A frequent problem when a dict is printed rather than serialised with json.dumps.

Frequently asked questions

My JSON is valid here but my API still rejects it, why?

Because syntactic validity and correctness are different things. This confirms a parser will accept the document; it says nothing about whether the keys, types and required fields match what the API expects. For that you need validation against a JSON Schema.

Why does the reported column point past the actual mistake?

Because a parser fails where it can no longer continue, not where the mistake was made. A trailing comma only becomes an error at the closing brace after it, and an unclosed string only fails at the end of the file. The likely-cause note exists to bridge that gap.

Can I use comments in JSON?

No. The specification has no comment syntax, and a // or /* */ makes the document invalid. If you need comments in configuration, use JSONC, JSON5 or YAML, but be sure whatever reads the file supports the one you pick.

Does it check for duplicate keys?

No, because the parser does not treat them as an error. In a document with the same key twice, the last value wins silently. It is a real source of bugs and it is not a syntax error, so nothing here will flag it.

Why use this rather than the formatter, which also reports errors?

The formatter is for producing output, indented or minified text you copy elsewhere. This is for diagnosis: it shows the failing line, marks the position and names the cause. Both parse the same way; they are built around different questions.

Compared with