Python
json
ValueError
json.loads
error-handling

Python json.loads shows ValueError Extra data

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The ValueError: Extra data error occurs when json.loads() receives a string containing more than one JSON value. The JSON spec defines a single root value per document, so if your string has multiple JSON objects concatenated together (common in log files, streaming APIs, or JSONL formats), the parser fails after successfully reading the first value. The fix depends on the format: split on newlines for JSONL, wrap in an array, or use a streaming decoder.

The Error

python
1import json
2
3# Two JSON objects concatenated — not valid JSON
4data = '{"name": "Alice"}{"name": "Bob"}'
5
6json.loads(data)
7# ValueError: Extra data: line 1 column 18 (char 17)

The parser successfully reads {"name": "Alice"} but then finds unexpected data starting at character 17 — the second {. JSON only allows one root value per string.

Cause 1: Multiple JSON Objects (JSONL / Newline-Delimited JSON)

The most common source — a file with one JSON object per line:

python
1# data.jsonl contents:
2# {"name": "Alice", "age": 30}
3# {"name": "Bob", "age": 25}
4# {"name": "Charlie", "age": 35}
5
6# WRONG — reads entire file as one string
7with open("data.jsonl") as f:
8    data = json.loads(f.read())  # ValueError: Extra data
9
10# CORRECT — parse each line separately
11with open("data.jsonl") as f:
12    records = [json.loads(line) for line in f if line.strip()]
13
14print(records)
15# [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}, ...]

Cause 2: Concatenated API Responses

Some streaming APIs return multiple JSON objects without delimiters:

python
1# Concatenated response from a streaming API
2response_text = '{"id": 1, "status": "ok"}{"id": 2, "status": "ok"}'
3
4# WRONG
5json.loads(response_text)  # ValueError: Extra data
6
7# CORRECT — use JSONDecoder.raw_decode() to parse one at a time
8decoder = json.JSONDecoder()
9results = []
10idx = 0
11while idx < len(response_text):
12    obj, end_idx = decoder.raw_decode(response_text, idx)
13    results.append(obj)
14    idx = end_idx
15    # Skip whitespace between objects
16    while idx < len(response_text) and response_text[idx] in ' \t\n\r':
17        idx += 1
18
19print(results)
20# [{'id': 1, 'status': 'ok'}, {'id': 2, 'status': 'ok'}]

raw_decode() parses one JSON value and returns the position where it stopped, letting you continue parsing the rest.

Cause 3: Trailing Content

Extra whitespace, comments, or garbage after valid JSON:

python
1# Trailing comma (invalid JSON)
2json.loads('{"name": "Alice",}')
3# JSONDecodeError (not Extra data, but related)
4
5# Trailing text
6json.loads('{"name": "Alice"} some extra text')
7# ValueError: Extra data
8
9# Fix: strip the string or extract just the JSON portion
10import re
11raw = '{"name": "Alice"} some extra text'
12match = re.match(r'(\{.*\})', raw)
13if match:
14    data = json.loads(match.group(1))

Cause 4: json.load() vs json.loads()

python
1# json.load() reads from a file object
2with open("data.json") as f:
3    data = json.load(f)  # Correct for single JSON file
4
5# json.loads() reads from a string
6data = json.loads('{"key": "value"}')
7
8# Common mistake — passing a file object to json.loads()
9with open("data.json") as f:
10    data = json.loads(f)  # TypeError, not ValueError
11    # Should be: json.loads(f.read()) or json.load(f)

Solution: Parse JSONL Files Robustly

python
1import json
2
3def parse_jsonl(filepath):
4    """Parse a JSONL file, skipping blank lines and handling errors."""
5    results = []
6    with open(filepath) as f:
7        for line_num, line in enumerate(f, 1):
8            line = line.strip()
9            if not line:
10                continue
11            try:
12                results.append(json.loads(line))
13            except json.JSONDecodeError as e:
14                print(f"Skipping line {line_num}: {e}")
15    return results
16
17records = parse_jsonl("data.jsonl")

Solution: Wrap Concatenated Objects in an Array

If you control the data format, wrap objects in an array:

python
1# Instead of:
2# {"a": 1}{"b": 2}{"c": 3}
3
4# Produce:
5# [{"a": 1}, {"b": 2}, {"c": 3}]
6
7# Quick fix for existing concatenated data
8raw = '{"a": 1}{"b": 2}{"c": 3}'
9fixed = '[' + raw.replace('}{', '},{') + ']'
10data = json.loads(fixed)
11# [{'a': 1}, {'b': 2}, {'c': 3}]

This approach is fragile — it breaks if the JSON values contain }{ inside strings. Use raw_decode() for robust parsing.

Using pandas for JSONL

python
1import pandas as pd
2
3# pandas handles JSONL natively
4df = pd.read_json("data.jsonl", lines=True)
5print(df)
6#      name  age
7# 0   Alice   30
8# 1     Bob   25
9# 2  Charlie  35

Common Pitfalls

  • Confusing JSON and JSONL: A .json file should contain one JSON value. A .jsonl file has one JSON object per line. Using json.load() on a JSONL file causes Extra data.
  • replace('}{', '},{') hack: Breaks if a string value contains }{. Use raw_decode() or line-by-line parsing instead.
  • Empty lines in JSONL: json.loads("") raises JSONDecodeError. Always strip and skip empty lines.
  • BOM (byte order mark): Files saved with UTF-8 BOM have \ufeff at the start. Use open(file, encoding='utf-8-sig') to strip it automatically.
  • Streaming APIs: Libraries like requests can stream JSON — use response.iter_lines() with json.loads() per line instead of response.text.

Summary

  • ValueError: Extra data means the string contains more than one JSON value
  • For JSONL (one object per line): parse each line separately with json.loads(line)
  • For concatenated objects: use json.JSONDecoder().raw_decode() to parse sequentially
  • Use pandas.read_json(file, lines=True) for JSONL files in data workflows
  • Always validate your JSON format — json.loads() expects exactly one root value

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.