json.dumps() separators= Silently Produces Broken JSON (tested)
json.dumps(d, separators=(item_sep, key_sep)) takes the two separator strings in a specific order. Get that order backwards and json.dumps() happily returns syntactically broken JSON — no exception, no warning. We measured exactly what breaks and why it's easy to get wrong.
1. The correct, common "minify" recipe
import json
d = {"a": 1, "b": 2}
json.dumps(d)
'{"a": 1, "b": 2}'
json.dumps(d, separators=(",", ":"))
'{"a":1,"b":2}'
Measured: separators takes a 2-tuple of (item_separator, key_separator) — the first string goes between items in an object or array, the second goes between a key and its value. (",", ":") is the standard "minify" recipe copied all over the internet, and it works correctly here.
2. Swap the order, and json.dumps() doesn't complain
json.dumps(d, separators=(":", ","))
'{"a",1:"b",2}'
Measured: this is obviously not valid JSON — commas and colons are in the wrong places — but json.dumps() returned it with no exception and no warning. The function does not validate that the item separator and key separator differ, or that either one is even a sensible JSON token; it just interpolates whatever strings you give it.
3. Passing the same string for both is accepted too
json.dumps(d, separators=(",", ","))
'{"a",1,"b",2}'
Measured: no distinct key/value marker at all, and still zero error at dump time. The mistake only surfaces downstream, when something tries to read this string back as JSON.
4. The failure shows up later, on the parsing side
broken = json.dumps(d, separators=(":", ","))
json.loads(broken)
json.decoder.JSONDecodeError: Expecting \':\' delimiter: line 1 column 5 (char 4)
Measured: the exact same "Expecting ':' delimiter" error covered in our delimiter guide, except here the cause is on the writing side, not the reading side — whoever wrote this JSON did it wrong, and whoever reads it will see an error that gives no hint the real bug is in a separators= argument three files away.
5. How to get this right every time
Remember the order as "comma before colon," matching how a normal (non-swapped) JSON object reads left to right: items are separated by , first, keys and values by : second — so the tuple is always (",", ":") for minified output, never the reverse. If you only want to drop the default's extra spaces without compacting fully, pass separators=(", ", ": ") (with the same order, just keeping the spaces) rather than guessing at a custom pair. There's no built-in validation to catch a swapped tuple, so if this code path isn't covered by a round-trip test (dump then immediately re-parse), a swap can ship silently.
Frequently asked questions
What order do the two values in json.dumps()'s separators= tuple go in?
We confirmed it's (item_separator, key_separator) — the first string separates items in an object or array, the second separates a key from its value; the standard minify recipe is separators=(\",\", \":\").
Does json.dumps() validate the separators= argument?
No — we measured that swapping the tuple order, or even passing the same string for both values, produces output with zero error or warning at dump time; json.dumps() just interpolates whatever strings it's given with no sanity check.
If separators= is wrong, when does the error actually appear?
Not at dump time — we confirmed the broken JSON string is returned successfully, and the error only surfaces later when something calls json.loads() on it, raising the same Expecting ':' delimiter error covered in our JSON delimiter guide, with no indication the real cause was a swapped separators= tuple.
What's the correct separators= value to fully minify JSON?
We tested and confirmed separators=(\",\", \":\") removes all whitespace between items and key-value pairs, producing the smallest valid JSON output, as opposed to the default (\", \", \": \") which includes a space after each.
How can I catch a swapped separators= argument before it ships?
We'd add a round-trip test — call json.loads() immediately on whatever json.dumps() with a custom separators= produces, in the same test — since there's no validation inside json.dumps() itself to catch the mistake automatically.
Written with AI assistance. Measured on 2026-10-03 with Python 3.13.5's built-in json module, calling json.dumps() with various separators= tuples and then feeding the output back through json.loads(), printing the exact results. PlainHeaders is our extension; Python's json module is built in.