Expecting property name enclosed in double quotes

The parser was at a spot where a key has to begin, just after a { or just after a comma, and the next character was not a double quote. In JSON every key is a string, and every string is double-quoted. There is no second option.

How the message appears

CPython's json module reports line, column and character offset. The position given is where the key should have begun, not where the mistake was typed.

  • json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 3 (char 4)
  • json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 4 column 1 (char 38)

The fix

Put double quotes around every key and every string value, and delete any comma sitting before a } or ]. If the text came out of Python, generate it again with json.dumps(obj) rather than str(obj) or an f-string.

Fails to parse
{
  'name': 'Ada',
  'roles': ['admin', 'editor']
}
Parses
{
  "name": "Ada",
  "roles": ["admin", "editor"]
}

The example travels in the URL fragment, which browsers never send to a server.

What causes it

A printed Python dict

str({'name': 'Ada'}) gives you {'name': 'Ada'}. It looks so close to JSON that it gets pasted into files and request bodies all day long. The single quotes are the giveaway. This is where the message comes from more often than anything else.

A trailing comma before the closing brace

The comma promises another key and the } does not deliver one, so Python complains about the missing key instead of the comma. The column it reports is the closing brace, one line below the line you actually need to edit.

Unquoted keys

{name: "Ada"} is a perfectly good JavaScript object and not valid JSON. Anything copied out of JS source, a YAML file or a MongoDB shell lands here.

A comment inside the object

JSON has no comments. A # or // line between two keys puts the wrong character exactly where the parser was waiting for a quote.

Worth knowing

  • If what you have really is Python source and not JSON, ast.literal_eval is the right tool. It is not a JSON parser though, and it is not a substitute for one.
  • Python's error is more helpful than it first looks. The char offset is where the key should have started, so the mistake is almost always the character immediately before it.

Written by Vishnu Shankar.

Your JSON and text are processed entirely in your browser and are never sent anywhere. To understand how the site is used we record each page view (the page, the referrer and an approximate location from your IP address) and keep it for 90 days. Nothing is stored on your device unless you choose it. Accept to also store a device identifier here and record your browser and device characteristics, which is what lets a return visit be told from a new one. Decline and nothing is sent at all. We respect Do Not Track. See our privacy policy.