JSON Formatter and Validator: Validate, Fix and Format JSON in One Pass
Paste a payload and there are really two questions to answer. Can this text be parsed at all, and can a person read it once it parses? Those are the jobs of a validator and a formatter, and keeping them apart is what turns a ten minute staring contest into a one minute fix. Here is how both halves work, and how to run them in the order that actually solves the problem.
What each half actually does
A validator takes text and answers a single question: is this well formed JSON under RFC 8259? It walks the document from the first character to the last and either builds a value or reports the first character it could not accept. It never changes your text, and it does not know or care what the fields are supposed to mean.
A formatter takes the same text and makes it readable. It adds indentation and line breaks so a nested object becomes a tree you can scan instead of a single wall of characters. It has to parse first, because you cannot reprint a structure you never built in the first place.
That is why almost every serious tool fuses them. The formatter needs the parser anyway, so it shows the parser's verdict in the same pass, and you get a readable result and a yes or no answer from one paste.
| Job | Question it answers | Changes your text | Checks your data contract |
|---|---|---|---|
| Validator | Is this parseable JSON? | No | No |
| Formatter | Can a human read it? | Yes, whitespace only | No |
| Schema validator | Does it match my fields? | No | Yes |
Readability and validity are independent. A perfectly indented document can still hold a trailing comma that makes it unparseable, and a dense one line response can be completely valid. The formatter improves the first property, the validator proves the second.
The small grammar the validator is enforcing
JSON is defined by RFC 8259, published by the IETF in December 2017, and it fits in about nine pages. The brevity is the point. The grammar is tiny enough that the same document parses to the same value in every conforming library, which is exactly what you want when two systems built in different languages have to exchange data.
A document is a single value: an object, an array, a string, a number, true, false or null. Objects hold comma separated "key": value pairs inside braces, arrays hold comma separated values inside brackets. Everything else is a syntax error, even when it looks reasonable to a human.
The rules that trip people up are few and consistent:
- Keys and string values use double quotes only. Single quotes and backticks are not JSON.
- No trailing comma after the last element of an object or an array.
- No comments, neither
//nor/* */. - Every key is quoted, even when it looks like an ordinary name.
- The only literals are
true,falseandnull, and all three are lowercase. - Numbers use a plain decimal form: no leading zeros, no hex, no
NaNorInfinity. - Control characters inside strings have to be escaped, so a real newline becomes
\n.
There is also a rule people forget until it bites them: the document must contain exactly one top level value with nothing after it. Two objects glued together are not one document, and the parser will stop at the start of the second one.
Reading an error position without losing time
When the parse fails, the message tells you where the parser gave up, not where you made the mistake. The parser reads left to right and stops at the first character it cannot handle, and that character is often one token after the real problem. A missing comma on line 12 can surface as an error on line 14, because the parser kept reading until the next token contradicted what it expected.
Two message families cover most of what you will see. Unexpected token means the parser met a character that is not allowed where it stood. Unexpected end of input means something was never closed, so an opening brace or a quote has no partner. And a very specific one, Unexpected token <, almost always means the server returned an HTML error page instead of JSON, so you are looking at a 404 or a 500 body and not your data at all.
The raw browser message gives you a character offset like at position 2847, which tells you nothing in a thousand line file. A validator earns its keep by translating that offset into a line and column, so you jump to the row instead of counting characters by hand. That translation is the whole reason a browser tool beats squinting at the console.
The mistakes behind almost every failed parse
Nearly every parse failure in the wild comes back to a short list, and nearly all of them come from writing JSON as if it were JavaScript or Python source.
| You pasted | What the parser stops at | The fix |
|---|---|---|
{"a": 1,} | The comma before the closing brace | Delete the trailing comma, in objects and arrays alike |
{'a': 'x'} | A single quote where a double quote belongs | Replace every single quote with a double quote |
{a: 1} | An unquoted property name | Quote the key: {"a": 1} |
{"a": 1 // note} | Comment characters where a value should start | Strip the comment; JSON has no comment syntax |
{"a": 1 "b": 2} | A value where a comma was expected | Add the missing comma between the two pairs |
{"n": 007} | A leading zero the grammar forbids | Write the number without the padding |
{"n": NaN} | A value JSON has no literal for | Send null, or send the value as a string |
A byte order mark before { | An invisible character ahead of the first token | Save the file as UTF 8 without a BOM |
Two of these deserve a second look. Duplicate keys are not a syntax error at all, because RFC 8259 says keys should be unique but does not forbid repeats, so the document parses and most parsers simply keep the last value. That silent drop is worse than an error message, and a syntax checker that just wraps the parser cannot show you the value that vanished. The byte order mark is the other one, an invisible marker some editors write at the top of a file that sits before the first token and makes a strict parser reject a document that looks perfectly fine.
Valid JSON is not the same as a valid contract
This is the mistake that costs teams the most time, so it is worth stating plainly: a green "valid JSON" check means the text is a JSON value, and nothing more. It does not mean age is an integer, that items is an array, or that userId matches the field your API expects.
The syntax validator and the schema validator ask different questions. Syntax asks "can I parse this?". Schema asks "does the parsed value match my contract?". Consider {"age": "30"}. It is valid JSON, and a schema that says age is an integer will reject it. Now consider {"age": 30} with a schema that requires minimum: 0: valid JSON, and it still fails if you send -1. The syntax check smiles through both.
JSON Schema is itself a JSON document, defined by the drafts at json-schema.org, with draft 2020-12 as the current stable version. It adds the checks a grammar cannot express: required fields, data types, value ranges, string patterns, array constraints and conditional rules. When the JSON feeds a contract, validate the syntax first and the schema second, and keep the two jobs honest by not blaming the grammar for a field the schema was meant to catch. A syntax tool that "repairs" valid JSON by deleting required fields until a schema you never read goes green has done you no favours at all.
A workflow that uses both halves in order
When you are debugging a payload you did not write, the order matters more than the tool. Here is the sequence that keeps each step honest.
First, paste the raw text and validate. If it fails, you have a syntax bug and there is nothing else to check until it passes. Read the reported line, remember the error often sits one token after the real mistake, and fix the character there.
Second, once the document is valid, format it with the indent you prefer and read the structure. The field that was invisible in the minified line is now a row in a tree, and a missing key or an unexpected error envelope is obvious.
Third, check the counters. The character total and the number of object keys tell you quickly whether the response is the object you expected or something shorter, like a truncated body or a stripped down error object.
Fourth, if the payload feeds a contract, run it against your schema after the syntax passes. Only then do you have both halves of the story: parseable and correct.
Fifth, when you are about to ship the payload back out, minify it and copy the compact form. For a config file someone will edit by hand, keep the formatted version instead. Either way the value is unchanged, because formatting and minifying are both lossless.
JSON Lines: validate one record at a time
Log data and event streams often arrive as JSON Lines, also called NDJSON, where every line is a complete JSON document of its own. If you paste the whole file into a validator it will fail, and the failure is not a bug in your data. The file as a whole is not one JSON document, it is many, and the parser is right to refuse it.
Validate one non empty line at a time instead. When a line fails, keep that record and its line number, because the position inside the line is what points at the broken quote or the stray comma. This is where a browser validator is genuinely faster than a command line: you paste the line, read the line number, fix it, and move on without writing a script for a one off cleanup.
Where your data actually goes
Tokens, session cookies, customer records and internal hostnames all travel inside JSON payloads, so where the text ends up when you paste it is a real question and not a theoretical one. A client side formatter never sends your document anywhere: the parsing and reprinting happen inside the tab with the browser's own engine, and the network panel stays empty while you work.
You can confirm that for yourself. Open the developer tools, switch to the network tab, paste a document and press format. No request carries your text, and the page keeps working when the network is offline. A payload you would never drop into a chat window or an issue tracker is exactly the kind of thing this property is for.
Frequently Asked Questions
01What is the difference between a JSON formatter and a JSON validator?
A formatter makes JSON readable by adding indentation and line breaks. A validator checks whether the text follows the syntax rules and can be parsed. Many tools combine both, and the useful order is to validate first and format second, so you are never reading output built from a document that never parsed.
02Why does my JSON fail here but work in my code?
Because most code is not parsing JSON. JavaScript object literals, Python dictionaries and editor config files accept trailing commas, single quotes and comments, while the JSON grammar allows none of them. A strict parser flags exactly what your language quietly tolerated, which is the same thing that would break at the API boundary later.
03How do I find the syntax error in a long document?
Paste it and validate. The message names the first character the parser could not accept and, where the browser reports a position, the line number appears next to it. Look one or two characters before that spot, and if the reported position sits past the end of the text, look for an unclosed bracket or an unfinished string instead.
04Can a validator fix my invalid JSON for me?
No, and you should be sceptical of anything that claims to. A missing quote or a stray comma can sometimes be guessed, but a repair that quietly changes the meaning of a document is worse than a clear error you can act on. Fix the character where the error points and re run the check.
05Is it safe to paste an API token into an online validator?
Only if the tool runs entirely in your browser. This one does, and you can verify it in the network panel. If you cannot confirm that for a tool, paste a redacted sample instead and keep the real credential out of it until you have checked.
06Do I need JSON Schema if I already validate the syntax?
Only when the data feeds a contract. Syntax validation answers whether the document parses; schema validation answers whether the parsed value has the fields and types your application expects. For a one off paste, syntax is enough. For anything crossing a system boundary, the schema check catches the errors a grammar was never designed to see.
Dallas, TX · SO reputation 7994 · Badges: 2🥇57🥈63🥉 · SO member since 2010