Most “JSON is broken” bug reports come down to one of three things, and it's almost never the tool that's wrong.
Trailing commas
JavaScript object literals allow this and JSON does not:
{
"name": "Ada",
"role": "engineer",
}That trailing comma after "engineer" is valid in a JS file, invalid in a JSON file. If you copy an object literal straight out of your editor and paste it into a JSON validator, this is almost always the first error you'll hit.
Single quotes and unquoted keys
{ name: 'Ada' } is convenient JS shorthand. JSON requires double quotes on both keys and string values, no exceptions:
{ "name": "Ada" }NaN, undefined, and Infinity aren't valid values
JSON.stringify({ x: NaN }) in a browser console will silently give you back {"x":null} — JavaScript quietly converts it. But if something upstream writes NaN or undefined directly into a JSON string (some Python serializers do this by default with allow_nan=True), it's technically invalid JSON and a strict parser will reject it even though it looks harmless.
What “pretty-print” is actually doing
Pretty-printing doesn't change the data — it re-serializes the same parsed structure with indentation. If your JSON has duplicate keys (yes, this is legal per the spec, and yes, different parsers handle it differently — most keep the last one), pretty-printing will silently drop the earlier duplicate because by the time it's formatting, it's already working from the parsed object, not the raw text. If you need to catch duplicate keys specifically, that's a different check than formatting.
Sorting keys before you diff
If you're about to compare two JSON blobs by eye, sort the keys first. Two semantically identical objects with keys in a different order will otherwise look different at a glance, and you'll waste time chasing a difference that isn't there. For an actual structural diff (not just visual), use a real JSON diff tool instead of eyeballing formatted output.