How to validate JSON and read parser error messages
Check JSON syntax, decode common parser errors, and learn why valid JSON can still be wrong for your API. Includes JavaScript and Python examples.
A parser saying "Unexpected token } in JSON at position 87" is not very friendly, but it contains exactly the clue you need. Validating JSON is really two jobs: confirming the text follows the JSON grammar, and confirming the data has the shape your code expects. This guide handles the first job in detail, shows how to do it in code and in the terminal, and then explains why the second job needs a different tool.
Syntax validity and data validity are different things
A JSON validator in the everyday sense checks syntax. It asks whether the text can be parsed according to the grammar in RFC 8259. That is a yes or no question, and the answer is the same in every conforming parser.
Whether the parsed data is acceptable is a separate question. The document {"age": "twenty"} is perfectly valid JSON, but if your application expects age to be a number, it is wrong. Checking that kind of thing requires a schema, such as JSON Schema, or validation code in your application. Start with syntax, because nothing else can be checked until the text parses.
It helps to think of validation as layers. The first layer is the grammar: are the brackets balanced, are the strings quoted properly, are the literals spelled correctly. The second layer is types and structure: is this field a number, is that array allowed to be empty. The third layer is business rules, such as an end date having to fall after a start date, and no schema language handles all of those well. Each layer has its own failure messages, and mixing them up is the reason people say a validator told them the data was fine when the application then crashed.
The mistakes behind most invalid documents
After reading a lot of broken payloads, the same handful of causes keep showing up. Trailing commas come first, usually left behind when someone deletes the last item in a list. Next are single-quoted strings and unquoted keys, which are legal in JavaScript but not in JSON. Comments are the third, common in config files that people assume are JSON-with-comments. Then there are unescaped characters inside strings: a raw double quote, a backslash in a Windows path such as C:\temp, or a literal newline.
Less obvious ones include a byte order mark at the start of a file, numbers like .5 or 5. or 007, and values like NaN or undefined that were dumped from a program. Truncated documents, where a download or a log line was cut off, produce an error at the end of the input. The example below contains three separate problems.
{
"name": "build-agent",
"path": "C:\temp\logs",
"retries": 03,
"labels": ["linux", "x64",],
}Validate in JavaScript
The built-in JSON.parse is a validator that happens to return a value. Wrap it in try and catch, and report the error message. Modern engines include more detail than they used to: V8 in recent Node and Chrome versions prints a snippet of the surrounding text, while older versions only gave a character position. Firefox and Safari word their messages differently, so do not match on error text in code.
function checkJson(text) {
try {
JSON.parse(text);
return { ok: true };
} catch (err) {
return { ok: false, message: err.message };
}
}
console.log(checkJson('{"a": 1,}'));
// { ok: false, message: 'Expected double-quoted property name in JSON at position 8 ...' }Validate from the command line
In a shell script or CI step you want an exit code. Both Python and jq return non-zero when the input does not parse, and both print the location of the failure. The exact message and exit code depend on the version you have installed, so the output below is one real run, not a promise. Python reports a line and column, which is easier to use than a raw character offset in a multi-line file.
$ cat config.json
{
"a": 1,
"b": 2,
}
$ python3 -m json.tool config.json > /dev/null
Illegal trailing comma before end of object: line 3 column 9 (char 20)
$ jq empty config.json
jq: parse error: Expected another key-value pair at line 4, column 1
$ echo $?
5Reading the error message
Parsers report the position where they gave up, not necessarily where the mistake was made. A missing closing quote on line 10 may only be noticed on line 12, when the parser hits a character that cannot continue the string. When the reported position looks fine, look backwards: check the previous line for a missing comma or an unclosed bracket.
Messages like "Unexpected token u in JSON at position 0" almost always mean you passed the string "undefined" to JSON.parse, often because a variable was empty. "Unexpected token < in JSON at position 0" means the response is HTML, typically an error page or a login redirect, and the real problem is the HTTP status, not the JSON. "Unexpected end of JSON input" means the text was empty or cut off.
Checking the shape of valid data
Once the text parses, you can validate structure. JSON Schema lets you declare which properties are required, what types they have, and what ranges are allowed, and libraries such as Ajv for JavaScript and jsonschema for Python can check a document against it. For smaller projects, a few explicit checks in code are enough, as long as you fail early with a clear message instead of letting an undefined value travel through your program.
A useful habit is to validate at the boundary: when data arrives from an API, a file, or a user, check it once there, and treat the checked value as trustworthy afterward. It also gives you a single place to log what an unexpected payload looked like.
Validating in the browser
When you just have a snippet in a ticket or a chat message, a browser validator is the fastest route. In View My JSON, paste the text or drop a .json file and use Validate; Format and Validate are free, and the text is parsed locally rather than sent to a server. If it passes, you can go straight to viewing it as Cards, Table, or Tree to confirm the fields are what you expected.
Do keep in mind what a green result means. It tells you the syntax is correct and nothing more. The values may still be wrong for your application, which is why the second half of validation, checking the shape of the data, belongs in your code or your schema.