Unterminated string starting at: line N column N (char N)
json.decoder.JSONDecodeError: Unterminated string starting at: line 3 column 11 (char 23)
Where JSON.parse stops
{
"id": 7,
"name": "Ada LovWhat it means
Python opened a string and reached the end of the document before the string closed. So the body was most likely cut off. The position is where the string started, not where the text ends.
Last verified on Python 3.9, 3.11, 3.12, 3.13 and 3.14.
The validator opens with the error marked. Examples travel in the URL fragment, which browsers never send to a server.
Express Lint lays broken JSON out by bracket depth and marks the line where it stops. It changes only spaces and line breaks outside strings. Strings in either quote stay as written. If the quotes do not pair up, it leaves your text as it is. Ctrl+Z undoes it. See how it works.
- Usually
- The body was cut offExpecting ',' delimiter: a missing quote on one lineInvalid control character: a missing quote across lines
- Fix
- Get the whole document.
The fix
Get the whole document. In the example the rest of the string and the closing } are missing, and the fixed version has both. If the text really was cut off, no edit brings the missing part back, so find out why it stopped.
{
"id": 7,
"name": "Ada LovLines 3 and 4 change.
{
"id": 7,
"name": "Ada Lovelace"
}How the message appears
CPython's json module reports line, column and character offset. The offset in the first line is where the string started, not where the document ends. The next two are what a missing closing quote gives when the string does not run to the end. Python 3.9 to 3.14 print the same for all three.
- json.decoder.JSONDecodeError: Unterminated string starting at: line 3 column 11 (char 23)
- json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 17 (char 16)
- json.decoder.JSONDecodeError: Invalid control character at: line 2 column 25 (char 26)
What causes it
The body was cut off
A response that stopped halfway, a file that was only partly written, or a buffer that was too small. The document ends in the middle of a string, as the example does, so Python runs out of text before the closing quote. Compare the length of what you got with what was sent, and find out why it stopped.
Expecting ',' delimiter: a missing quote on one line
If a closing quote is missing but more text follows on the same line, the string ends at the next quote it finds. In
{"name": "Ada, "id": 7}the string runs from"Ada,to the quote beforeid, so Python reports a missing comma at thei. See Expecting ',' delimiter.Invalid control character: a missing quote across lines
In a document with line breaks, a string with no closing quote runs on to the end of its line. The line break is not allowed inside a string, so Python reports
Invalid control character atand the position is that line break. See Invalid control character.
Worth knowing
NoteIn the example, char 23 is the opening quote of "Ada Lov. Python reports where the string began so you can find the string that never closed.