Unexpected non-whitespace character after JSON: data za koncem

JSON text obsahuje právě jednu hodnotu, kolem ní smí být jen bílé znaky (RFC 8259, oddíl 2). Když parser dočte první objekt nebo pole a za ním najde další znak, hlásí v Node.js a Chromu Unexpected non-whitespace character after JSON, v Pythonu Extra data. Nejčastěji jde o JSON Lines čtené jako jeden JSON nebo o závorku navíc.

Autor: Aktualizováno

Znění hlášky v jednotlivých prostředích

Pozice v hlášce ukazuje na první znak za koncem prvního úplného dokumentu. PHP hlásí jen obecné Syntax error, .NET popíše znak, který po hodnotě nečekal.

Parser Hláška Kdy
Node.js 25, Chrome 153 (V8) JSON.parse, response.json(), Edge a další prohlížeče s V8 Unexpected non-whitespace character after JSON at position 9 (line 2 column 1) Dva dokumenty za sebou (JSON Lines čtené jako JSON)
Unexpected non-whitespace character after JSON at position 11 (line 1 column 12) Závorka navíc na konci
Python 3.14 json.loads, json.load (json.JSONDecodeError) Extra data: line 2 column 1 (char 9) Dva dokumenty za sebou (JSON Lines čtené jako JSON)
Extra data: line 1 column 12 (char 11) Závorka navíc na konci
Python 3.9 starší verze, např. systémový Python v macOS Extra data: line 2 column 1 (char 9) Dva dokumenty za sebou (JSON Lines čtené jako JSON)
Extra data: line 1 column 12 (char 11) Závorka navíc na konci
.NET 10 (System.Text.Json) JsonDocument.Parse, JsonSerializer.Deserialize '{' is invalid after a single JSON value. Expected end of data. Dva dokumenty za sebou (JSON Lines čtené jako JSON)
']' is invalid after a single JSON value. Expected end of data. Závorka navíc na konci
PHP 8.4 json_last_error_msg(), JsonException s JSON_THROW_ON_ERROR Syntax error Dva dokumenty za sebou (JSON Lines čtené jako JSON), Závorka navíc na konci

Příčiny a opravy

Dva dokumenty za sebou (JSON Lines čtené jako JSON)

Chybně
{"id":1}
{"id":2}
Opraveno
[{"id":1},{"id":2}]

Soubory .jsonl a .ndjson, logy a exporty mívají jeden dokument na řádek. Celý soubor tedy není JSON, ale posloupnost JSON textů. Čti ho po řádcích a každý řádek parsuj zvlášť, nebo ze záznamů sestav pole, pokud příjemce chce jeden JSON.

JavaScript: JSON Lines po řádcích
// data.jsonl: jeden JSON dokument na řádek
const rows = text
  .split('\n')
  .filter((line) => line.trim() !== '')
  .map((line) => JSON.parse(line));
Python: JSON Lines po řádcích
import json

with open('data.jsonl', encoding='utf-8') as f:
    rows = [json.loads(line) for line in f if line.strip()]

Formát a jeho pravidla (UTF-8, konec řádku za každým záznamem) popisuje kapitola JSON Lines a NDJSON.

Závorka navíc na konci

Chybně
{"a":[1,2]}]
Opraveno
{"a":[1,2]}

Závorka nebo čárka navíc za koncem dokumentu zůstane nejčastěji po ruční úpravě nebo po skládání JSON z řetězců. Formátovač v JSON validátoru odsadí dokument podle závorek, takže je vidět, kde první hodnota končí. JSON vytvářej serializátorem (JSON.stringify, json.dumps, json_encode), ne spojováním textu.

Jak najít příčinu

  • Podívej se, co stojí na hlášené pozici. Začíná tam { nebo [, jde o další dokument; je tam } nebo ], je v textu závorka navíc.
  • Je-li pozice na začátku druhého řádku, jsou to skoro jistě JSON Lines.
  • U odpovědi API zkontroluj, jestli server neposílá víc objektů za sebou bez obalujícího pole, nebo jestli se k JSON nepřipojil další výstup (ladicí výpis, varování PHP).

Dokumenty spojené bez oddělovače ({"id":1}{"id":2}) rozdělí v Pythonu json.JSONDecoder().raw_decode: vrátí první hodnotu a pozici, kde skončila, a další dokument čteš od ní.

Python: první dokument a pozice jeho konce
import json

decoder = json.JSONDecoder()
value, end = decoder.raw_decode('{"id":1}{"id":2}')
# value == {'id': 1}, end == 8: druhý dokument začíná na pozici 8