Extra data: line 1 column N (char N)
json.loads parses exactly one JSON value. This message means it parsed one successfully and then found more text afterwards — so the document is not malformed so much as it is two documents. The offset is where the second one begins.
How the message appears
CPython's json module reports line, column and character offset. Here the offset is where the second document starts, which is the most useful number on this page.
What causes it
It is JSON Lines, not JSON
One complete JSON object per line, no commas, no enclosing array. .jsonl and .ndjson files are deliberately this shape, and so is the output of most log pipelines and many streaming APIs. It is not broken; it needs a different reader.
A file that was appended to
A script that opens with mode a and calls json.dump on each run produces a file with several documents stacked in it. Each one is valid; the file as a whole is not a single value.
Two responses concatenated
A proxy or a retry that wrote both bodies to the same buffer. The offset lands exactly where the second { starts, which is how you tell this apart from a syntax error inside one document.
The fix
Decide which format you actually have. For JSON Lines, parse each line on its own: [json.loads(line) for line in f if line.strip()]. For a single document, wrap the values in [ ] and separate them with commas, as the fixed sample shows.
{"id": 1, "name": "Ada"}
{"id": 2, "name": "Grace"}[
{"id": 1, "name": "Ada"},
{"id": 2, "name": "Grace"}
]The example travels in the URL fragment, which browsers never send to a server.
Worth knowing
- Do not convert a
.jsonlfile into an array without checking what reads it. JSON Lines exists so a huge file can be streamed one record at a time without holding it all in memory — turning it into an array throws that away. json.JSONDecoder().raw_decode(text)parses one value and returns the index it stopped at, which is the supported way to walk a stream of concatenated documents.