Expecting Property Name Enclosed in Double Quotes (tested)
This error means json.loads() found something where a "key" should be, and it wasn't a double-quoted string. There are exactly three common causes, and one of them is a single easy-to-miss mistake that produces data which looks right until you actually try to parse it.
1. Single quotes instead of double quotes
import json
json.loads("{\'a\': 1}")
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Measured: JSON requires double quotes for every string, including object keys — single quotes are not valid JSON at all, even though they're interchangeable with double quotes in Python and JavaScript string literals. This is the single most common cause: pasting a Python dict's repr() or a JavaScript object literal directly as if it were JSON.
2. An unquoted key (valid JavaScript, invalid JSON)
json.loads("{a: 1}")
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Measured: identical error and position to the single-quote case. JavaScript object literals allow bare identifier keys ({a: 1}); JSON never does — every key must be a quoted string, full stop. Hand-written "JSON" copied from JS source code is a frequent source of this.
3. The sneaky one: str(a_python_dict) instead of json.dumps()
d = {"a": True, "b": None, "c": (1, 2)}
s = str(d)
print(s)
{'a': True, 'b': None, 'c': (1, 2)}
json.loads(s)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Measured: str() and repr() on a Python dict produce Python syntax — single-quoted keys, and also True/None/(tuples) instead of JSON's true/null/arrays. This looks correct at a glance in a log line or an f-string, and it's the easiest version of this bug to introduce by accident: logging a dict with f"{my_dict}" or str(my_dict) then later feeding that logged string back through json.loads(). The fix is always json.dumps(d) to produce it, never str(d).
4. Related: a missing colon or comma are different errors
json.loads('{"a" 1}')
json.decoder.JSONDecodeError: Expecting \':\' delimiter: line 1 column 6 (char 5)
json.loads('{"a": 1 "b": 2}')
json.decoder.JSONDecodeError: Expecting \',\' delimiter: line 1 column 9 (char 8)
Measured: these are worded and reported distinctly from the property-name error above, which makes the message itself diagnostic: "property name" means the key syntax is wrong (wrong quote style or missing quotes entirely); "':' delimiter" means a valid-looking key was found but nothing separates it from its value; "',' delimiter" means two key-value pairs ran together with nothing between them.
5. How to tell which mistake you made
If the position in the error (column 2 in all three single/unquoted/str(dict) examples above) points right after the opening {, the problem is the key itself: check for single quotes, missing quotes, or — if the string came from a Python log statement or an f-string — whether it was ever actually passed through json.dumps() or just printed as a raw dict. A ':' or ',' delimiter error means the keys themselves are fine and the problem is the punctuation between fields instead.
Frequently asked questions
What does "Expecting property name enclosed in double quotes" mean?
We confirmed it means json.loads() reached a position where a quoted object key should start and found something else — single quotes, no quotes at all, or (most commonly by accident) Python's str()/repr() syntax instead of real JSON.
Why does str(my_dict) look like JSON but fail to parse?
Because we measured that Python's str() and repr() on a dict produce Python literal syntax — single-quoted keys plus True/None/tuples instead of JSON's true/null/arrays — which reads as JSON-like in a log line but is not valid JSON; the fix is always json.dumps(), never str() or an f-string, to serialize a dict.
Is {a: 1} (unquoted key) valid JSON?
No — we confirmed it raises the same "Expecting property name enclosed in double quotes" error as single-quoted keys; JSON requires every key to be a double-quoted string, unlike JavaScript object literals which allow bare identifier keys.
How is this different from an "Expecting ':' delimiter" error?
We measured these as distinctly worded and positioned: the property-name error means the key syntax itself is wrong, while the ':' delimiter error means a valid key was parsed successfully but nothing separates it from its value — the message tells you which side of the colon has the problem.
What's the single most common real-world cause of this error?
In our testing, pasting or logging a Python dict with str() or an f-string and later trying to json.loads() that string back — it looks identical to JSON when printed, single quotes and all, but was never actually serialized as JSON in the first place.
Written with AI assistance. Measured on 2026-10-03 with Python 3.13.5's built-in json module, calling json.loads() on each malformed string and printing the exact exception text. Every message below is copy-pasted output, not paraphrased. PlainHeaders is our extension; Python's json module is built in.