Why JSON is strict, and why that's the point
If you've ever written a JavaScript object literal, JSON looks almost identical, and that similarity is exactly what gets people in trouble. JavaScript objects are forgiving. JSON is not.
JSON has no comments. Not //, not /* */, nothing. It has no trailing commas. It requires double quotes around every key and every string value, no exceptions, no single quotes. There's no way to write a function, a date object, or undefined. Just objects, arrays, strings, numbers, booleans, and null.
This rigidity isn't an oversight. JSON was designed to be a data interchange format, meaning its whole job is to move data reliably between systems that might be written in completely different languages. A parser in Python, a parser in Java, and a parser in JavaScript all need to agree on exactly one way to read a given piece of text. Comments, trailing commas, and unquoted keys are all things a language can be flexible about when humans are the only ones reading the code. When machines on both ends need to agree without ambiguity, flexibility is the enemy.
Think about what happens without that agreement. If one parser decided trailing commas were fine and another didn't, the same file would be valid on one server and broken on another. If comments were allowed, every parser would need its own opinion on what counts as a comment and where it's allowed to appear, adding complexity for a feature that has nothing to do with moving data. JSON's designers chose to leave all of that out on purpose, trading flexibility for a format that behaves identically everywhere, on every platform, in every language, forever.
So the strictness that feels annoying when you're hand-editing a config file is the same strictness that makes JSON trustworthy as an API response format, a config format, and a storage format across the entire industry. It's a deliberate design decision, not a missing feature. Once you see it that way, the errors below stop feeling like arbitrary gotchas and start feeling like predictable consequences of a format that refuses to guess what you meant.
The syntax errors that come up constantly
Almost every JSON error a developer hits falls into one of a handful of categories. Once you know them, you can usually spot the shape of the problem even before a validator points to the exact line.
- A trailing comma. Broken:
{"name": "Alex", "role": "admin",}. Fixed:{"name": "Alex", "role": "admin"}. That last comma after the final property is invalid, and it's one of the most common copy-paste errors when someone reorders or deletes a property by hand. - Single quotes instead of double quotes. Broken:
{'name': 'Alex'}. Fixed:{"name": "Alex"}. Single quotes are valid in JavaScript and Python, but never in JSON. - An unquoted key. Broken:
{name: "Alex"}. Fixed:{"name": "Alex"}. Unquoted keys are legal in a JS object literal, which is exactly why this mistake is so common when copying code between the two. - A missing comma between properties. Broken:
{"name": "Alex" "role": "admin"}. Fixed:{"name": "Alex", "role": "admin"}. This one is especially easy to miss because both halves still look like perfectly valid JSON on their own.
A few more show up often enough to be worth naming. Using NaN, undefined, or a JavaScript Date object as a value: none of those exist in JSON, only strings, numbers, booleans, objects, arrays, and null. Leaving a number wrapped in quotes when it shouldn't be, or vice versa, which usually doesn't break parsing but does break whatever expects a specific type on the other end. And mismatched brackets, closing an object with ] instead of }, which is an easy typo when you're nesting arrays of objects several levels deep.
Every one of these is a one-character fix once you know exactly where it is. The hard part is finding it.
Why "eyeballing it" doesn't scale
A five-line JSON object with a syntax error is easy to fix by reading it. A 200-line API response, nested four levels deep, with one missing comma buried somewhere in the middle, is a completely different problem. Your eyes skim past matched brackets and quotes without registering the one place they don't line up.
This is where a validator earns its keep. Instead of scanning the whole payload yourself, a proper JSON validator parses the text the same way any JSON.parse() call would, and when it hits something it doesn't expect, it tells you the exact line and character where parsing failed. What might take you five minutes of careful re-reading takes the validator a fraction of a second.
This matters even more when the JSON didn't come from a person typing it out. A lot of broken JSON shows up after it's been passed through several systems: an API that returns a truncated response because a request timed out mid-stream, a log file that got two JSON objects concatenated together without a separator, or a config file that someone edited in a text editor that silently swapped in "smart quotes" instead of straight ones. None of those problems look wrong at a glance. They only show up when something actually tries to parse the text.
The bigger the JSON payload, the more the manual approach breaks down. A validator's job gets easier as the file gets bigger, not harder.
There's also a speed argument that has nothing to do with error-finding. Even valid JSON is often hard to read when it comes back from an API as one unbroken line of text. Before you can debug the actual problem, an unformatted response, you usually need to format it first just to see what you're looking at.
Formatting (pretty-printing) vs minifying
JSON has two useful shapes, and they serve different purposes.
- Pretty-printed (formatted) JSON is indented, with one property per line and consistent spacing. It's for humans: reading an API response in a debugger, reviewing a config file, or scanning a payload for the field you need. Nobody should be reading minified JSON with their eyes.
- Minified JSON strips out every unnecessary space, tab, and line break. It's for production: a smaller payload means less data to transmit over the network, which matters at scale even though a single request feels identical either way.
A good JSON tool should do both without friction, letting you switch between "make this readable" and "make this small" depending on what you're doing at the moment. There's no reason to keep two separate tools around, or to write your own script, for something this common.
It's also worth knowing that formatting and minifying are lossless in both directions. Pretty-printing a minified response and then minifying it again gets you back to the exact same bytes, just with the whitespace removed. Neither operation touches the actual data, only how it's laid out on the page, which is why it's safe to reformat JSON as many times as you need while you're working through a problem.
Debugging faster with a formatter/validator
The fastest JSON debugging workflow looks like this: paste the raw JSON in, let the tool validate it instantly, jump straight to the line and character it flags, fix the one character that's wrong, and re-check. No manual bracket-counting, no guessing.
Our own free JSON Formatter & Validator does exactly this in the browser. It pretty-prints JSON for readability, minifies it for production, and validates it instantly, pointing straight to the exact syntax error location instead of leaving you to hunt for it. It's free, there's no sign-up, and nothing you paste is uploaded anywhere since the whole thing runs locally in your browser.
That last part matters more than it sounds. A lot of the JSON developers paste into online tools is real: API keys buried in a response body, customer records, internal config. A browser-based tool that processes everything with local JavaScript, rather than shipping your paste to a server first, means you get the same instant feedback without having to think twice about what you're pasting in.
A typical session looks like this: copy a broken API response straight from your browser's dev tools or terminal output, paste it into the formatter, and read the error message it gives you, something like "Unexpected token } in JSON at position 142." Fix the flagged character, paste again, and you're done. No editor plugin to install, no command-line tool to remember the flags for, just a page you can keep open in a tab all day.
Next time a payload throws a cryptic parse error, skip the eyeballing and let a validator find the exact spot for you.