Python’s json.loads expects one JSON document. If another value follows a completed first value, it can raise JSONDecodeError with an Extra data message. Do not fix that error by silently keeping the first object or assuming every newline separates records. First establish the producer’s actual output format.
This matters for inventory exports, configuration imports and API response files. A successful import that drops later records can be more misleading than a visible parsing failure. Preserve the original input while investigating.
Separate one document from multiple records
A JSON array containing two objects is one document. Two objects written consecutively are not one ordinary JSON document, even if each object would parse individually. Whitespace before or after a document is allowed; another value is different from whitespace.
Pretty-printed JSON can span many physical lines. Splitting such a document into lines and parsing each line independently breaks its structure. Conversely, an explicitly agreed line-delimited format normally places each complete record on one physical line. That is a separate input contract, not an automatic interpretation of every file with a .json extension.
Reproduce the boundary with harmless input
Save this complete example as a disposable Python file and run it with Python 3. It uses in-memory sample data and does not read or rewrite production files. The assertions check the accepted and rejected cases.
import json
accepted = [
(' {"id": 1} ', {"id": 1}),
('[{"id": 1}, {"id": 2}]', [{"id": 1}, {"id": 2}]),
('{\n "id": 1\n}', {"id": 1}),
]
for text, expected in accepted:
assert json.loads(text) == expected
rejected = [
'{"id": 1}{"id": 2}',
'{"id": 1}\n{"id": 2}',
'{"id": 1} trailing',
]
for text in rejected:
try:
json.loads(text)
except json.JSONDecodeError as exc:
assert exc.msg == 'Extra data'
print('Rejected extra data at:', exc.lineno, exc.colno)
else:
raise AssertionError('Unexpectedly accepted extra data')
print('Single-document boundary checks passed')
The test accepts a pretty-printed object and rejects newline-separated objects. That difference shows why replacing json.loads with a line loop is not a neutral repair. It changes the supported format.
Investigate the producer before changing the reader
Ask whether the file should contain a single configuration object, an array of records, or an agreed stream format. Check the export documentation and inspect a small authorised sample. Avoid posting full payloads into support tickets: they may contain personal information or access tokens.
Python’s documentation warns that JSON is not a framed protocol. Repeatedly calling json.dump on separate objects into the same file does not produce a valid single-document JSON file. If that is the producer’s bug, correct the export format deliberately and test every consumer rather than trimming the reader’s input until it stops complaining.
For a small collection intended to be one document, the producer can encode an array. For an established line-delimited integration, use a reader designed for that contract, with explicit blank-line, record-type and failure policies. Do not convert a large export to one in-memory array without considering memory requirements.
Keep boundaries and validation distinct
A correctly parsed document can still contain duplicate names or inappropriate values. The related tutorial on rejecting duplicate JSON keys in configuration addresses ambiguity inside objects. It does not establish where a document ends.
The decoder’s raw_decode method returns a value and the index where decoding ended. That is useful when implementing a deliberate stream parser, but ignoring the remaining suffix can silently discard data. Do not substitute it merely to suppress Extra data.
Avoid exception handling that converts every parsing failure into an empty list. Keep invalid syntax visible, record the error position without logging the whole document, and stop downstream processing until the input contract is reconciled. For untrusted input, also apply appropriate size and resource limits before parsing.
Quick questions and import checklist
Does Extra data always mean two objects? No. A valid first value followed by other non-whitespace content can cause it, including accidental text appended by an export process.
Does valid JSON always mean an object? No. Python also parses arrays and scalar values. Validate the required application structure separately after parsing.
- Preserve the failing original and identify its producer.
- Agree whether the integration expects one document or explicit records.
- Test pretty printing, trailing whitespace and multiple values.
- Verify record totals before accepting a repaired export.
Source: Python’s JSON documentation, including framing, decoding errors and raw_decode.
This tutorial is for educational purposes. Test carefully before production use. The site owner is not responsible for misuse, damage, data loss or production issues.



