json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes

Quick answer

Python’s JSON parser expected an object key wrapped in double quotes but found something else — single quotes, an unquoted key, or a trailing comma. JSON only allows double quotes for keys and strings. The usual cause is feeding json.loads() a Python dict converted with str() instead of json.dumps().

The exact error string

The traceback ends with a line that names the position of the offending character:

Traceback (most recent call last):
  File "app.py", line 5, in <module>
    data = json.loads(text)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Unlike Expecting value: line 1 column 1 (char 0) — where the whole string is not JSON — this error means parsing started fine (it saw an opening {) but then hit a key that is not a double-quoted string.

Where this error usually comes from

The five most common situations that produce this error:

Cause 1: Single quotes instead of double quotes

This is by far the most common cause. A Python dict converted to a string with str() uses single quotes, which are valid Python but invalid JSON:

import json

text = "{'name': 'Alice', 'age': 30}"   # single quotes — looks like a Python dict
data = json.loads(text)
# JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

The parser reads the {, then expects a " to start the first key — but finds a ' at column 2. JSON requires double quotes everywhere.

Cause 2: A trailing comma

A comma after the last item makes the parser expect another key, but it finds the closing brace:

import json

text = '{"name": "Alice", "age": 30,}'   # trailing comma after 30
data = json.loads(text)
# JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 29 (char 28)

Here the position points at the } — the parser wanted a new key there. Remove the comma after the final value. (See the JavaScript version of this issue in JSON Trailing Comma.)

Cause 3: Unquoted keys (JavaScript-style)

JavaScript object literals allow bare keys; JSON does not. Copying an object straight out of JS source produces invalid JSON:

import json

text = '{name: "Alice", age: 30}'   # unquoted keys
data = json.loads(text)
# JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Every key must be wrapped in double quotes: {"name": "Alice", "age": 30}.

Diagnose in three steps

Before reaching for a fix, run print(repr(text)) on the string you are passing to json.loads(). The repr() output makes quote style and invisible characters visible at a glance:

print(repr(text))
# "{'name': 'Alice', 'age': 30}"    ← outer double, inner single → Cause 1
# '{"name": "Alice", "age": 30,}'   ← ends with ,}               → Cause 2
# '{name: "Alice", age: 30}'        ← bare word before colon      → Cause 3

Match what you see to the fix:

What repr() shows Root cause Fix
starts with {' Single quotes (Python repr) ast.literal_eval()json.dumps()
contains ,} or ,] Trailing comma Remove the comma after the last item
{word: (no quotes) Unquoted JS-style key Wrap every key in "

The right fix depends on what you have

If you have a real Python dict

Do not build JSON by hand or with str(). Use json.dumps(), which always emits valid double-quoted JSON:

import json

obj = {"name": "Alice", "age": 30}
text = json.dumps(obj)          # '{"name": "Alice", "age": 30}'  ✓ valid JSON
data = json.loads(text)         # round-trips cleanly

If you have a string that looks like a Python dict

When the single-quoted text comes from a log, a database column, or str(dict) output, convert it back to a real dict with ast.literal_eval() (safe), then re-serialize with json.dumps():

import ast
import json

text = "{'name': 'Alice', 'age': 30}"   # single-quoted Python dict literal

obj = ast.literal_eval(text)   # safely → {'name': 'Alice', 'age': 30}
clean_json = json.dumps(obj)   # '{"name": "Alice", "age": 30}'  ✓
data = json.loads(clean_json)

Never use eval() on untrusted input — ast.literal_eval() only evaluates literals and is safe for this purpose.

If the JSON is hand-written

Fix it at the source: replace single quotes with double quotes, quote every key, and remove trailing commas. Paste it into a validator to catch every issue at once.

Fix invalid JSON in seconds

Paste the bad JSON into the validator — it reports the exact line, column, and character that caused the failure:

# Input
{'name': 'Alice'}

# Validator output
Line 1, column 2: Expecting property name enclosed in double quotes

# Input
{"name": "Alice", "age": 30,}

# Validator output
Line 1, column 29: Expecting property name enclosed in double quotes
JSON Validator JSON Formatter

Frequently Asked Questions

What does Expecting property name enclosed in double quotes mean?

It means Python's json parser expected the next thing inside an object to be a key wrapped in double quotes, but found something else — a single quote, an unquoted word, or a closing brace after a trailing comma. JSON requires every object key to be a double-quoted string. The most common cause is feeding json.loads() a Python dict converted to text with str() instead of json.dumps().

Why does single-quoted JSON fail in Python?

The JSON specification only allows double quotes for strings and keys. A string like {'name': 'Alice'} is valid Python but invalid JSON, so json.loads() rejects it at the first single quote. Convert Python objects to JSON with json.dumps(), which always emits double quotes.

How do I convert a Python dict string to JSON?

If you have a real Python dict, use json.dumps(my_dict). If you only have a string that looks like a Python dict (with single quotes), use ast.literal_eval() to safely turn it back into a dict, then json.dumps() to serialize it correctly. Never use eval() on untrusted input.

Does a trailing comma cause this error?

Yes. A trailing comma after the last item in an object — like {"a": 1,} — makes the parser expect another key after the comma, but it finds the closing brace instead. JSON does not allow trailing commas. Remove the comma after the final item.

Are unquoted keys allowed in JSON?

No. JavaScript object literals allow unquoted keys like {name: "Alice"}, but JSON does not. Every key must be a double-quoted string: {"name": "Alice"}. If you are copying an object from JavaScript source, you must quote every key before it is valid JSON.

About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.