Common causes
1. A dict converted with str() instead of json.dumps()
str(d), print(d), f-strings and logging all produce Python syntax with single quotes. The receiving side then fails on the first key. Serialize with json.dumps.
r.set("order:1182", str(order))r.set("order:1182", json.dumps(order))2. A trailing comma before the closing brace
After a comma Python expects another key. Python 3.13 and later report this case as “Illegal trailing comma before end of object” instead.
{"order_id": 1182, "paid": true,}{"order_id": 1182, "paid": true}3. Unquoted keys from JavaScript
JavaScript object literals such as {orderId: 1182} are not JSON. Quote every key, or have the JavaScript side send JSON.stringify(obj).
{orderId: 1182, paid: true}{"orderId": 1182, "paid": true}4. Data that is really a Python literal
If a file or column already contains Python-style text, do not patch the quotes with replace; it breaks on apostrophes. Read it with ast.literal_eval once and write proper JSON back.
data = json.loads(row["payload"].replace("'", '"'))data = ast.literal_eval(row["payload"])
row["payload"] = json.dumps(data)Frequently asked questions
Why not just replace ' with "?
A blind replace breaks strings that contain apostrophes, such as “O’Brien”, and leaves True and None in place. Use ast.literal_eval to read Python literals, or Fix it in PasteKit, which understands the string boundaries.
Can Python's json module accept single quotes?
No, and it has no option for it. Third-party parsers such as json5 or demjson accept relaxed syntax, but fixing the producer is more reliable.
Is this the same as the JavaScript error "Expected property name or '}'"?
Yes, it is the same rule reported by a different parser. The JavaScript version of this error covers browser and Node wording.