Przejdź do treści
HNarzędzia
pl
Kategorie

Dla programistów

Błąd w JSON: jak znaleźć i poprawić najczęstsze problemy

Parser zgłasza „Unexpected token” albo „Nieoczekiwany znak” i nie mówi, co dokładnie jest nie tak. Sprawdź, co dla każdego z typowych błędów pokazuje walidator, jak czytać wskazaną linię i kolumnę oraz kiedy poprawny JSON i tak zmienia dane.

Błędy w JSON zwykle są jedną z kilkunastu typowych pomyłek: przecinek po ostatnim elemencie, pojedyncze cudzysłowy, klucz bez cudzysłowu, komentarz, NaN albo plik ucięty w połowie. Parsery zgłaszają je krótko („Unexpected token”), więc pomaga narzędzie, które wskaże linię, kolumnę i pokaże fragment ze znacznikiem. Wklej dokument do formatowania JSON, przeczytaj pierwszy błąd, popraw go i wklej ponownie. Dokument jest przetwarzany w przeglądarce i nie trafia na serwer.

Jak czytać linię, kolumnę i znak

Narzędzie podaje trzy liczby, np. „Linia 9, kolumna 3 (znak 162)”. Linia i kolumna liczą się od 1. „Znak” to indeks liczony od 0 (pierwszy znak dokumentu to znak 0), taki sam jak w komunikacie przeglądarki („at position 162”). Pod linią z błędem narzędzie pokazuje znacznik ^.

Trzy rzeczy warto wiedzieć od razu:

  • Walidator zatrzymuje się na pierwszym błędzie. Dokument z sześcioma pomyłkami wymaga sześciu poprawek (przykład poniżej).
  • Wskazane miejsce to pierwszy znak, którego parser nie umie przyjąć, a nie zawsze miejsce pomyłki. Brakujący przecinek na końcu linii 3 jest zgłaszany na początku linii 4.
  • Linijka „Komunikat przeglądarki” pod błędem pochodzi z silnika przeglądarki i jest po angielsku. Jej treść zależy od przeglądarki, a pomiary robiliśmy w Chromium. Linię, kolumnę i opis po polsku wylicza własny walidator narzędzia.

Co pokazuje walidator dla typowych błędów

Dokument testowy to syntetyczne zamówienie (10 linii, 165 bajtów). W każdym pliku z błędem zmieniliśmy dokładnie jedną rzecz i wkleiliśmy go do narzędzia. Pozycje są z interfejsu narzędzia (wersja PL).

Co jest w pliku Wskazana pozycja Opis w narzędziu
Przecinek po ostatnim elemencie tablicy ({ ... }, przed ]) linia 9, kolumna 3 (nawias ]) Przecinek przed zamknięciem obiektu lub tablicy jest niedozwolony
Przecinek po ostatnim polu obiektu (], przed }) linia 10, kolumna 1 (nawias }) ten sam komunikat
Pojedyncze cudzysłowy wokół wartości: 'Anna Nowak' linia 3, kolumna 15 Nieoczekiwany znak, powinna być wartość
Klucz bez cudzysłowu: paid: true linia 4, kolumna 3 Oczekiwano nazwy klucza w podwójnym cudzysłowie
Komentarz // w osobnej linii linia 2, kolumna 3 Komentarze // i /* */ są niedozwolone w JSON
Komentarz /* ... */ po przecinku linia 4, kolumna 17 ten sam komunikat o komentarzach
NaN, undefined albo Infinity jako wartość linia 5, kolumna 15 Nieoczekiwany znak, powinna być wartość
Typograficzne cudzysłowy wokół wartości: “Anna Nowak” linia 3, kolumna 15 Nieoczekiwany znak, powinna być wartość
Typograficzne cudzysłowy wokół klucza linia 3, kolumna 3 Oczekiwano nazwy klucza w podwójnym cudzysłowie
Twarda spacja (U+00A0) po dwukropku linia 4, kolumna 10 Nieoczekiwany znak, powinna być wartość
Niewidoczna spacja zerowej szerokości (U+200B) przed true linia 4, kolumna 11 Nieoczekiwany znak, powinna być wartość
Brak przecinka między polami linia 4, kolumna 3 Oczekiwano przecinka lub zamknięcia obiektu
Brak dwukropka: "paid" true linia 4, kolumna 10 Oczekiwano dwukropka po nazwie klucza
Zero wiodące: 01042 linia 2, kolumna 13 Niepoprawna liczba
+1042, .5 linia 2, kolumna 12 Nieoczekiwany znak, powinna być wartość
Liczba szesnastkowa 0x41 linia 2, kolumna 13 Oczekiwano przecinka lub zamknięcia obiektu
Ścieżka Windows "C:\Users\Anna" linia 3, kolumna 18 Niepoprawna sekwencja ucieczki
Enter wewnątrz tekstu w cudzysłowie linia 3, kolumna 20 Niedozwolony znak sterujący, użyj \n
Brakujący zamykający cudzysłów: "Anna Nowak, linia 3, kolumna 27 (koniec linii) Niedozwolony znak sterujący w tekście
Brakujący ] przed } linia 9, kolumna 1 Oczekiwano przecinka lub zamknięcia tablicy
Dwa dokumenty w jednym pliku albo tekst po zamykającym } linia 11, kolumna 1 Nadmiarowe dane po zakończeniu dokumentu
Odpowiedź HTML zamiast JSON (<!DOCTYPE html>) linia 1, kolumna 1 Nieoczekiwany znak, powinna być wartość

Co z tego wynika w praktyce:

  • Komentarz ma własny opis i podpowiedź, co zrobić (usunąć go albo przenieść opis do osobnego klucza). Klucz bez cudzysłowu dostaje opis „Oczekiwano nazwy klucza…”, a komunikat przeglądarki dla obu błędów jest taki sam („Expected property name…”).
  • Pojedyncze cudzysłowy wartości, NaN, undefined i Infinity też mają wspólny opis. Rozpoznasz je po pierwszym znaku pod ^.
  • Brakujący zamykający cudzysłów jest zgłaszany jako problem z końcem linii, a nie z cudzysłowem. Gdy komunikat mówi o znaku sterującym, a w linii nie ma żadnego Entera, sprawdź, czy tekst zamyka się cudzysłowem.
  • Przy brakującym przecinku i brakującym nawiasie narzędzie wskazuje następną linię. Przyczyna leży na końcu poprzedniej.

Znaki, których nie widać

Twarda spacja, spacja zerowej szerokości i cudzysłowy typograficzne wchodzą do JSON zwykle przez kopiowanie z edytora tekstu, dokumentu lub strony internetowej. Walidator wskazuje je poprawnie (patrz tabela), ale na ekranie wyglądają niewinnie: pod ^ stoi coś, co przypomina zwykłą spację albo nie widać nic.

Wskazówka z naszych pomiarów: gdy w komunikacie przeglądarki znak w apostrofach wygląda jak spacja albo apostrofy są puste (Unexpected token ' '), a linia wygląda poprawnie, to jest niewidoczny znak. Usuń fragment wskazany przez ^ i wpisz go ponownie z klawiatury. Typograficzne cudzysłowy “ i ” zamień na zwykłe ".

BOM na początku pliku

BOM (U+FEFF, w UTF-8 trzy bajty EF BB BF) to znacznik na początku pliku, który dodają niektóre programy. Plik testowy z BOM zachowuje się tak:

  • Narzędzie do formatowania ignoruje pojedynczy BOM na początku i pokazuje „Poprawny JSON”. Gdy BOM jest w wklejonym tekście, pod spodem pojawia się informacja: „Tekst zaczyna się od znaku BOM (U+FEFF). Wynik go nie zawiera, bo część programów odrzuca JSON z BOM”. Przy pliku wczytanym przyciskiem „Otwórz plik” informacji nie ma, bo przeglądarka usuwa BOM już przy odczycie pliku. Dwa BOM-y z rzędu dają błąd w linii 1, kolumnie 1.
  • Pobrany wynik („dane.json”, 196 bajtów) zaczyna się od {, bez BOM. Sformatowanie i pobranie pliku usuwa więc ten znak.
  • Ten sam plik w Node.js 24 (JSON.parse na tekście z fs.readFileSync(plik, 'utf8')) kończy się błędem „Unexpected token”, a w Pythonie 3.14 (json.load) komunikatem „Unexpected UTF-8 BOM (decode using utf-8-sig)”. Pomiary w Node i Pythonie zrobiliśmy lokalnie, poza narzędziem.

Dlatego sam „Poprawny JSON” w formatterze nie gwarantuje, że wczyta go każdy program. RFC 8259 (sekcja 8.1) zabrania dodawania BOM do JSON wysyłanego między systemami i pozwala parserom go pominąć, ale nie wymaga tego. Jeśli plik ma trafić do aplikacji, użyj pobranego wyniku.

Konwerter CSV-JSON w kierunku JSON do CSV usuwa BOM także z wklejonego tekstu, więc tekst z BOM przechodzi bez błędu.

Ucięty plik

Plik urwany w środku pobierania, wklejony fragment albo odpowiedź API przerwana limitem znaków kończą się tak samo: parser dochodzi do końca tekstu i brakuje mu zamknięcia. Dla pliku uciętego po { "sku": "B-7" narzędzie wskazało linię 8, kolumnę 19 (to miejsce, gdzie plik się kończy) i napisało „Nieoczekiwany koniec danych. Brakuje zamknięcia nawiasu, cudzysłowu lub wartości”. Dla pliku urwanego w środku tekstu "Anna Now wynik jest taki sam, z kolumną 24 w linii 3.

Jeśli „Nieoczekiwany koniec danych” pojawia się przy pliku, który nie powinien być ucięty, sprawdź, czy całość się skopiowała i czy dokument ma tyle samo { co } oraz [ co ]. Gdy plik pobrałeś lub dostałeś od kogoś, pobierz go jeszcze raz.

Podobny objaw ma odpowiedź serwera, która w ogóle nie jest JSON-em. Wklejony tekst zaczynający się od <!DOCTYPE html> daje błąd w linii 1, kolumnie 1, bo pierwszy znak to <. Zwykle oznacza to stronę błędu (np. 502 albo przekierowanie do logowania), więc sprawdź adres i odpowiedź serwera, a nie składnię.

JSON, JSON5 i obiekt JavaScript

Wiele „błędów w JSON” to poprawny zapis w innym formacie. Obiekt JavaScript pozwala na klucze bez cudzysłowu, pojedyncze cudzysłowy, komentarze, przecinek na końcu i NaN. JSON tego nie dopuszcza.

  • RFC 8259 (grudzień 2017, Internet Standard STD 90, sprawdzone w październiku 2026) opisuje gramatykę, w której elementy rozdziela przecinek, a po ostatnim go nie ma. Reguły na komentarze w niej nie ma. Liczby są dziesiętne, bez zer wiodących, a NaN i Infinity są niedozwolone (sekcja 6).
  • ECMA-404 w wydaniu drugim z grudnia 2017 (sprawdzone w październiku 2026) opisuje tę samą składnię.
  • JSON5 (sprawdzone w październiku 2026) jest osobnym formatem. Dodaje komentarze, przecinek na końcu, pojedyncze cudzysłowy, klucze bez cudzysłowu, liczby szesnastkowe, +1, .5 oraz Infinity i NaN. Walidator JSON uzna taki dokument za błędny.

Co z tym zrobić: jeśli plik jest konfiguracją z komentarzami, a program dopuszcza JSON5 lub JSONC, zostaw go. Jeśli ma trafić do API albo JSON.parse, usuń komentarze, ujmij klucze w ", zamień ' na ", usuń końcowe przecinki i zamień NaN oraz undefined na null albo pomiń to pole. Wartości null używaj świadomie, bo zmienia znaczenie danych.

Przykład: dokument z sześcioma błędami w siedmiu rundach

Dokument testowy jest zapisany jak mały obiekt JavaScript:

{
  // sklep
  name: 'Anna',
  "tax": NaN,
  "tags": ["a", "b",],
}

Wklejaliśmy go do narzędzia i po każdym komunikacie poprawialiśmy jedną rzecz:

Runda Wynik narzędzia Poprawka
1 linia 2, kolumna 3: oczekiwano nazwy klucza (komentarz //) usuń linię z komentarzem
2 linia 2, kolumna 3: oczekiwano nazwy klucza (name) zamień na "name"
3 linia 2, kolumna 11: nieoczekiwany znak (') zamień 'Anna' na "Anna"
4 linia 3, kolumna 10: nieoczekiwany znak (N z NaN) zamień NaN na null
5 linia 4, kolumna 21: przecinek przed zamknięciem tablicy usuń przecinek przed ]
6 linia 5, kolumna 1: przecinek przed zamknięciem obiektu usuń przecinek po ]
7 Poprawny JSON, 3 klucze, głębokość 2, 85 B gotowe

Pierwsze dwie rundy mają to samo wskazanie (linia 2, kolumna 3), bo po usunięciu komentarza zaczyna się tam klucz bez cudzysłowu.

Formatowanie JSON z dokumentem testowym zamówienia: komunikat „Linia 9, kolumna 3 (znak 162)” i znacznik pod zamykającym nawiasem kwadratowym po przecinku na końcu tablicy

Poprawny JSON nie oznacza niezmienionych danych

Gdy walidator pokazuje „Poprawny JSON”, składnia jest w porządku. Wartości mogą się jednak różnić od wejścia, bo narzędzie czyta dokument przez JSON.parse i zapisuje go przez JSON.stringify. Liczby są wtedy 64-bitowymi liczbami zmiennoprzecinkowymi. W takich przypadkach pod zielonym komunikatem pojawiają się żółte ostrzeżenia. Plik testowy z liczbami dał takie wyniki:

Na wejściu Na wyjściu Ostrzeżenie
9007199254740993 (2^53 + 1) 9007199254740992 tak (linia 2, kolumna 9)
12345678901234567890 12345678901234567000 tak (linia 3, kolumna 10)
0.1000000000000000055 0.1 tak (linia 7, kolumna 11)
1e400 null tak
9007199254740991 (2^53 - 1) bez zmian nie
1.10 1.1 nie
1e2 100 nie

Formatowanie JSON z plikiem liczb testowych: po lewej 9007199254740993 i 12345678901234567890, po prawej 9007199254740992 i 12345678901234567000, a pod spodem zielony komunikat „Poprawny JSON” i trzy żółte ostrzeżenia o liczbach, które zmieniły wartość

RFC 8259 w sekcji 6 zaznacza, że liczby całkowite od -(2^53)+1 do (2^53)-1 mają dokładne wartości, na które zgodzą się różne implementacje. Poza tym zakresem wynik zależy od programu. Ostrzeżenie wyjaśnia, co będzie w wyniku (np. „W wyniku będzie 9007199254740992”) i radzi zapisać identyfikator jako tekst w cudzysłowie. Zera końcowe i zapis wykładniczy (1.10, 1e2) nie są ostrzegane, bo zmienia się tylko zapis, a nie wartość. Dla numerów, identyfikatorów i kodów (EAN, numery kont, ID z baz danych) zapisuj wartość jako tekst: plik z "id": "9007199254740993" wraca bez zmian.

Zera końcowe w ułamku nie zmieniają wartości, ale zmieniają zapis: 1.10 staje się 1.1. Jeśli ten zapis jest ważny (np. cena porównywana jako tekst), przechowuj ją jako tekst.

Druga pułapka to powtórzone klucze. W pliku z dwoma kluczami "paid" (true, a potem false) narzędzie pokazało „Poprawny JSON” i w wyniku zostawiło ostatnią wartość false, a pod spodem ostrzeżenie: „Klucz „paid” powtarza się w tym samym obiekcie (linia 5, kolumna 3). Wynik zachowa tylko ostatnią wartość”. Według RFC 8259 (sekcja 4) nazwy w obiekcie powinny być unikalne, a zachowanie przy powtórzeniach jest nieprzewidywalne. Decyzję, którą wartość zostawić, musisz podjąć sam.

Konwerter CSV-JSON w kierunku JSON do CSV ma tę samą cechę, ale też ostrzega. Wklejony dokument z liczbami z powyższej tabeli dał w CSV 9007199254740992 i 12345678901234567000, a pod ustawieniami pojawiły się ostrzeżenia, np. „Liczba 9007199254740993 (linia 2, kolumna 9) nie mieści się w dokładności liczb JavaScriptu. W CSV znajdzie się 9007199254740992”. W kierunku CSV do JSON liczby całkowite większe niż 2^53 - 1 zostają tekstem: 9007199254740993 trafiło do wyniku w cudzysłowie, razem z kodem 00-950. Błędny JSON w konwerterze też dostaje pozycję, np. „Niepoprawny JSON: linia 9, kolumna 3” z tym samym opisem co w formatowaniu, ale bez fragmentu ze znacznikiem ^. Przy powtórzonym kluczu konwerter, tak jak formatowanie, ostrzega, że w CSV zostanie tylko ostatnia wartość (w naszym teście paid = false).

Formatowanie czy minifikacja

Formatowanie dodaje wcięcia i podziały linii, minifikacja usuwa zbędne białe znaki. Żadne z nich nie naprawia dokumentu: błędny JSON nie zostanie sformatowany ani zminifikowany, dopóki walidator nie przepuści go bez błędów.

Plik testowy zamówienia ma 165 B. Po przetworzeniu w narzędziu:

Tryb Wynik
Minifikuj 120 B
Formatuj, 2 spacje 196 B
Formatuj, 4 spacje 248 B

Wynik po formatowaniu jest większy od pliku wejściowego, bo narzędzie rozwija też obiekty zapisane w jednej linii ({ "sku": "A-1", "qty": 2 }). Sformatowany JSON pasuje do przeglądania w edytorze i porównywania zmian, a minifikowany do wysyłania w żądaniach i zapisu w konfiguracji. Opcja „Sortuj klucze alfabetycznie” ułatwia porównanie dwóch wersji tego samego dokumentu, ale zmienia kolejność kluczy w wyniku.

Czego narzędzie nie robi

  • Nie naprawia błędów samo. Pokazuje pierwszy błąd i opis, a poprawkę wprowadzasz Ty.
  • Nie sprawdza zgodności ze schematem (JSON Schema), tylko składnię.
  • Nie rozpoznaje JSON5 ani JSONC. Dokument z komentarzami zostanie uznany za błędny.
  • Pomiary komunikatów przeglądarki dotyczą Chromium. W innych przeglądarkach angielski komunikat może brzmieć inaczej, a pozycję i polski opis wylicza własny walidator narzędzia.