Neplatné číslo v JSON: Unexpected number a NaN

Číslo má zápis, který JSON nepovoluje: úvodní nulu (01), desetinnou čárku (12,50), NaN nebo Infinity. V8 v Node.js a Chromu hlásí úvodní nulu jako Unexpected number in JSON a NaN jako Unexpected token 'N'. Desetinná čárka vypadá jako chyba klíče, protože ji parser čte jako oddělovač.

Autor: Aktualizováno

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

Parser Hláška Kdy
Node.js 25, Chrome 153 (V8) JSON.parse, response.json(), Edge a další prohlížeče s V8 Unexpected number in JSON at position 10 (line 1 column 11) Úvodní nula
Expected double-quoted property name in JSON at position 11 (line 1 column 12) Desetinná čárka místo tečky
Unexpected token 'N', "{"pomer":NaN}" is not valid JSON NaN (stejně tak Infinity)
Firefox 158 JSON.parse, response.json() JSON.parse: expected ',' or '}' after property value in object at line 1 column 11 of the JSON data Úvodní nula
JSON.parse: expected double-quoted property name at line 1 column 12 of the JSON data Desetinná čárka místo tečky
JSON.parse: unexpected character at line 1 column 10 of the JSON data NaN (stejně tak Infinity)
Safari (WebKit 26) JSON.parse, response.json() JSON Parse error: Expected '}' Úvodní nula
JSON Parse error: Property name must be a string literal Desetinná čárka místo tečky
JSON Parse error: Unexpected identifier "NaN" NaN (stejně tak Infinity)
Python 3.14 json.loads, json.load (json.JSONDecodeError) Expecting ',' delimiter: line 1 column 11 (char 10) Úvodní nula
Expecting property name enclosed in double quotes: line 1 column 12 (char 11) Desetinná čárka místo tečky
projde bez chyby NaN (stejně tak Infinity)
.NET 10 (System.Text.Json) JsonDocument.Parse, JsonSerializer.Deserialize Invalid leading zero before '1'. Úvodní nula
'5' is an invalid start of a property name. Expected a '"'. Desetinná čárka místo tečky
'N' is an invalid start of a value. NaN (stejně tak Infinity)
PHP 8.4 json_last_error_msg(), JsonException s JSON_THROW_ON_ERROR Syntax error Úvodní nula, Desetinná čárka místo tečky, NaN (stejně tak Infinity)

Python ve výchozím nastavení NaN přijme, ačkoli to RFC 8259 nepovoluje. Data, která Python bez potíží načte, proto může jiný parser odmítnout.

Příčiny a opravy

Úvodní nula

Chybně
{"pocet":01}
Opraveno
{"pocet":1}

Další neplatné zápisy jsou +1, .5 a 1.. Identifikátor s úvodními nulami přenes jako řetězec (viz níže).

Desetinná čárka místo tečky

Chybně
{"cena":12,50}
Opraveno
{"cena":12.50}

Parser přečte 12, čárku vezme jako oddělovač položek a za ní čeká název další vlastnosti v uvozovkách. Proto hláška mluví o názvu vlastnosti, ne o čísle. JSON používá desetinnou tečku bez ohledu na jazyk uživatele. Oprav export, ne plošným nahrazením čárek, které patří i do textu.

NaN (stejně tak Infinity)

Chybně
{"pomer":NaN}
Opraveno
{"pomer":null}

JSON nemá hodnoty pro NaN ani nekonečno. Chybějící nebo nepočitatelnou hodnotu přenes jako null nebo pole vynech. V Pythonu zapni kontrolu na obou stranách:

Python: odmítnutí NaN a Infinity
import json

def odmitni(nazev):
    raise ValueError(f"{nazev} není platné číslo JSON")

json.loads('{"pomer":NaN}')                         # {'pomer': nan}, bez chyby
json.loads('{"pomer":NaN}', parse_constant=odmitni)  # ValueError: NaN není platné číslo JSON
json.dumps({"pomer": float("nan")})                  # '{"pomer": NaN}', neplatný JSON
json.dumps({"pomer": float("nan")}, allow_nan=False) # ValueError: Out of range float values …

Je údaj číslo, nebo identifikátor?

U množství znamená 01 obvykle číslo 1; u kódu výrobku mohou být úvodní nuly součástí identifikátoru. V takovém případě je správná oprava řetězec "01", nikoli odstranění nuly. Nejdřív zjisti význam pole a pravidla příjemce.

Platné číslo 1e+2 znamená 100: plus je povolené u exponentu, ale ne před celým číslem. Číslo 1e400 má správný zápis JSON, přesto může překročit rozsah cílového typu. Platná syntaxe nezaručuje ani přesnost: velká celá čísla mohou po načtení ztratit číslice. Další rozdíly popisuje kapitola Čísla v JSON.