In Node 22 and Chrome 150, Expected double-quoted property name means an object comma was not followed by a property name. {"a":1,} stops on }. Array trailing commas report Unexpected token ] and include no position.
Expected double-quoted property name in JSON at position N comes from JSON.parse. In Node 22 and Chrome 150, an object comma that is not followed by a "property name" produces that sentence. In {"a":1,}, position 7 is }. Delete the comma in front of it. A comment or a second comma after the first comma still uses this sentence. The character at the position is then / or ,.
A trailing comma in an array is a different sentence, and it has no position: Unexpected token ']', "[1,2,]" is not valid JSON. The named token is ].
This is not Unexpected token in JSON at position 0. That failure dies on the first character. These do not fail on the first character. If the message has position, read that index. If it does not, the character is inside Unexpected token '…'. Paste the raw text into the JSON formatter. One-click repair handles trailing commas, single quotes, unquoted keys, comments, and undefined / NaN / Infinity. Those three become null, and so does -Infinity. Read the values before you ship the repair. For a payload that is valid from the first byte, export one from the test data generator.
Python 3.9.6 reports an object trailing comma as Expecting property name enclosed in double quotes: line 1 column 8 (char 7). Index 7 is }. A single-quoted key and an unquoted key use the same sentence: index 1 is ' or a letter. An array trailing comma is Expecting value: line 1 column 6 (char 5). Index 5 is ].
try {
JSON.parse(raw)
} catch (e) {
const msg = String(e.message)
const at = msg.match(/position (\d+)/)
if (at) {
const i = Number(at[1])
console.log(msg, JSON.stringify(raw[i]))
} else {
console.log(msg)
}
}
When the message includes position, that index is the character that stopped the parse. In the rows below, ], a single-quoted string, and undefined / NaN / Infinity do not include position. The character is the Unexpected token.
Named character Likely cause
} after a comma Trailing comma in an object
token ] Trailing comma in an array
' Single quotes
A letter after { or a comma Unquoted key
" right after a value Missing comma
/ A comment
token u / N / I undefined / NaN / Infinity
JS and TS allow { a: 1, }. JSON does not.
JSON.parse('{"a":1,}')
// Expected double-quoted property name in JSON at position 7 (line 1 column 8)
{"a":1, } with a space moves the position from 7 to 8. The character is still }. JS and TS source allow { a: 1, }. Parsing that text as JSON throws. In Node, console.log({ a: 1 }) prints { a: 1 }, with no trailing comma. Delete the comma before }. VS Code JSONC (settings.json, tasks.json, launch.json) accepts a trailing comma and shows a warning. JSON.parse does not accept it. For an API body, call JSON.stringify. Do not paste a source object literal into the response.
JSON.parse('[1,2,]')
// Unexpected token ']', "[1,2,]" is not valid JSON
An object trailing comma asks for another property name and includes a position. The array message has no position. The token is ]. [1,,2] has a hole in the middle and throws Unexpected token ',', "[1,,2]" is not valid JSON, also with no position. JSON has no holes like that. Send JSON.stringify(arr), or omit the comma after the last element.
JSON.parse("{'a':1}")
// Expected property name or '}' in JSON at position 1 (line 1 column 2)
JSON.parse('{"a":\'x\'}')
// Unexpected token ''', "{"a":'x'}" is not valid JSON
In Python 3.9.6, str({'a': 1}) is "{'a': 1}", with single quotes on the key and the string. A JavaScript string can use single quotes too. JSON keys and strings must use double quotes. When you swap ' for ", escape any " that already sits inside the string as \".
JSON.parse('{a:1}')
// Expected property name or '}' in JSON at position 1 (line 1 column 2)
Node 22 and Chrome 150 use the same sentence as a single-quoted key: Expected property name or '}'. At position 1, a single-quoted key is '. An unquoted key is a letter, such as a in {a:1}. JSON5 allows that key. JSON.parse does not. Do not emit unquoted keys on a public API.
JSON.parse('{"a":1 "b":2}')
// Expected ',' or '}' after property value in JSON at position 7 (line 1 column 8)
In {"a":1 "b":2}, position 7 is ", not a comma. Put a comma between the two properties. A trailing comma is one comma too many. This one is a comma missing.
VS Code uses JSONC for settings.json, tasks.json, and launch.json, so // and /* */ are allowed there. JSON.parse rejects them.
JSON.parse('{"a":1 // x\n}')
// Expected ',' or '}' after property value in JSON at position 7 (line 1 column 8)
JSON.parse('{"a": /* x */ 1}')
// Unexpected token '/', "{"a": /* x */ 1}" is not valid JSON
A line comment and a missing comma share the sentence Expected ',' or '}'. In {"a":1 // x\n}, position 7 is /. On a missing comma, the character at the position is ". The block comment {"a": /* x */ 1} has no position. The token is /. Strip comments before JSON.parse or response.json(). Leave those VS Code files to the editor's JSONC mode. Do not pass them to JSON.parse.
Those are JavaScript values, not JSON.
JSON.parse('{"a": undefined}')
// Unexpected token 'u', "{"a": undefined}" is not valid JSON
JSON.parse('{"a": NaN}')
// Unexpected token 'N', "{"a": NaN}" is not valid JSON
JSON.parse('{"a": Infinity}')
// Unexpected token 'I', "{"a": Infinity}" is not valid JSON
On an object, JSON.stringify({ a: undefined, b: 1 }) returns {"b":1}. The undefined field is omitted. In an array it is not omitted: JSON.stringify([undefined]) is [null]. JSON.stringify({ a: NaN }) and JSON.stringify({ a: Infinity }) both write null. So does -Infinity. If the text still contains the words undefined, NaN, or Infinity, JSON.stringify did not produce it. On the wire, use null or omit the field. The in-browser repair replaces undefined, NaN, Infinity, and -Infinity with null. Parse then succeeds. The value has changed.
If the first character is <, empty, or [object Object], go back to Unexpected token in JSON at position 0. If JSON.stringify throws, see Converting circular structure to JSON. For a payload that must parse, use the test data generator. The JSON formatter flags syntax. After a repair, still check whether a field should have become null.
Related: JSON formatter · Blog index