json

FormatValidateConvert

Expected property name or '}' in JSON

Straight after an opening brace, JSON allows exactly two things: a key in double quotes, or the closing brace of an empty object. The parser found something else in that spot, at position 1 in the example, which is the character right after the {. Nine times out of ten the text is a Python dictionary or a JavaScript object literal that looks like JSON but is not.

Input

{'id': 7, 'name': 'Ada'}

Do

  1. Paste the input into the validator.
  2. Press Repair in the editor band.

Result

Converted single-quoted strings (3)

{"id": 7, "name": "Ada"}

Try it in the validator →

What each runtime prints for this input
RuntimeMessage
Chrome 153 · Node.js 26Expected property name or '}' in JSON at position 1 (line 1 column 2)
Node.js 18 (older V8)Unexpected token ' in JSON at position 1
Firefox 156JSON.parse: expected property name or '}' at line 1 column 2 of the JSON data
Safari 26JSON Parse error: Single quotes (') are not allowed in JSON
Python 3.14 jsonExpecting property name enclosed in double quotes: line 1 column 2 (char 1)
This siteExpected a quoted property name, found "'"line 1, column 2

Recorded from each runtime; the wording is in Firefox’s, Safari’s and Python’s sources.

Where the text came from

Look at the character the position points to, and it usually tells you which language produced the text.

  • A single quote is Python's signature. Printing a dictionary with print(d) or str(d) gives {'id': 7}, not JSON, and so does copying a value out of a debugger or a Jupyter cell. Python writes True, False and None the same way, so a longer dictionary fails on those next.
  • A bare word, as in {id: 7}, is a JavaScript object literal copied from source code or from the browser console, where keys need no quotes.
  • A comma, as in {,}, is usually a template or a string built in a loop that emitted a separator before the first item.
  • Nothing at all: a document cut off right after its opening brace also stops here, because the end of the text is not a key either.

Fix it where the text is made

The durable fix is to serialise with a real JSON encoder instead of printing a value. In Python that is json.dumps(d), which quotes every key and string with double quotes and spells the three literals as true, false and null. In JavaScript it is JSON.stringify(obj). Any text produced by joining strings together will eventually meet a value with a quote or a comma in it, so building JSON by hand is worth replacing even after this one error is gone.

import json
print(json.dumps({'id': 7, 'name': 'Ada'}))
# {"id": 7, "name": "Ada"}

If you only have the text, find and replace is tempting and risky: turning every ' into " also changes the apostrophe in "it's" and breaks a string that was fine.

Some projects work around the error by passing the text to eval or to a relaxed parser that accepts JavaScript syntax. Both accept far more than JSON, and eval will run whatever code the text contains, so neither belongs anywhere near data that came from another system.

How the runtimes word it

Chrome, Node.js 20 and later, and Firefox use nearly the same phrase, and Firefox's version comes with a line and a column. Safari is more direct when the culprit is a quote mark and says that single quotes are not allowed in JSON. Python asks for a property name enclosed in double quotes. Node.js 18 printed only Unexpected token followed by the character, so an old answer that quotes Unexpected token ' in JSON at position 1 is describing this same mistake.

Do not confuse this message with Expected double-quoted property name. That one appears after a comma rather than after an opening brace, and it nearly always means a trailing comma. The two differ by a few words and have completely different causes.

Fixing it here

In the JSON Validator, Code view underlines the first quote and names what the parser wanted there, as the last row of the table shows. Repair then rewrites the single-quoted strings with double quotes. It reads the text as it goes, so an apostrophe inside a string stays an apostrophe, and it quotes bare keys and translates Python's literals in the same pass. The status bar counts each kind of change, three converted strings for the example, and a single undo restores the original. For a longer walk-through with comments and trailing commas mixed in, read Fix invalid JSON.