Ricerca dei messaggi di errore JSON: dal testo dell'errore direttamente alla correzione
In sintesi: Identifica la causa dal messaggio esatto di JSON.parse: 12 errori frequenti su Chrome, Firefox e Safari, comprese pagine HTML di errore, troncamento e doppio parsing.

In sintesi: quando compare un errore di JSON.parse, prendi prima la posizione e il token; una posizione 0 significa verificare la presenza di una risposta HTML, di un BOM o di un tipo errato, e un messaggio "Expected" significa guardare il carattere precedente — non rileggere riga per riga dalla posizione riportata.
Il testo dell'errore non è rumore — è la risposta. Il parser ti dice quale carattere ha incontrato, cosa si aspettava e cosa ha effettivamente ricevuto. Cercare per messaggio di errore batte riscrivere a mano l'intero documento.
Ogni errore di JSON.parse() ha tre parti: la posizione (un offset di carattere, oppure riga/colonna), l'aspettativa (Expected...) e la realtà (Unexpected token X, oppure xxx is not valid JSON). Gli engine le formulano diversamente — Chrome e Node (V8) dicono Expected ',' or '}' after property value in JSON at position 25, Firefox dice JSON.parse: expected ',' or '}' after property value in object at line 3 column 1, Safari dice JSON Parse error: Expected ',' or '}' — ma tutti e tre indicano la stessa rottura sintattica. Quando cerchi un errore, ignora la formulazione e afferra i tre fatti: quale carattere, cosa era atteso, cosa è arrivato.
1. La tabella di ricerca dei 12 errori
La colonna di sinistra è il frammento più identificabile della tua console (formulazione V8). Le varianti di Firefox/Safari sono tra parentesi.
| Testo dell'errore (V8) | Causa reale | Correzione |
|---|---|---|
Unexpected token < in JSON at position 0 |
L'API ha restituito HTML (pagina 404, template 500, redirect al login, fallback del proxy), non JSON | Controlla prima response.status e Content-Type; non correggere il JSON |
Unexpected end of JSON input |
L'input è vuoto o troncato: corpo vuoto, 204, download interrotto, copia priva dell'ultima riga | Gestisci il caso vuoto, confronta Content-Length per trovare il taglio |
Unexpected token o / "[object Object]" is not valid JSON |
Un oggetto già analizzato è stato passato di nuovo a JSON.parse() ed è stato convertito in stringa |
Controlla typeof; se è un oggetto, usalo direttamente |
"undefined" is not valid JSON |
La variabile non è mai stata assegnata (JSON.parse(undefined)) |
Inizializza valori di fallback; controlla prima di fare il parsing |
Expected double-quoted property name in JSON |
Una virgola finale ({"a": 1,}); il parser si aspetta un'altra chiave e trova } |
Rimuovi la virgola dopo l'ultimo elemento |
Expected property name or '}' in JSON |
Una chiave senza virgolette o con apici singoli ({name: "Ada"}, {'name': 'Ada'}) |
Metti tra virgolette doppie ogni chiave |
Expected ',' or '}' after property value in JSON |
Una virgola mancante ({"a": 1 "b": 2}) o un commento dopo un valore |
Aggiungi la virgola; elimina il commento |
Unexpected token '/' |
Un commento // o /* */ dentro il JSON |
Rimuovilo, oppure analizza la configurazione come JSONC |
Bad control character in string literal |
Un a capo, un tab o un altro carattere di controllo U+0000–U+001F grezzo dentro una stringa | Scrivi \n; genera con JSON.stringify |
Unterminated string in JSON |
Una stringa aperta con " e mai chiusa, o una virgoletta interna non sottoposta a escape |
Sottoponi a escape le virgolette interne come \" |
Unexpected non-whitespace character after JSON |
Due documenti in un unico testo: {}{}, NDJSON, un wrapper JSONP |
Dividi per righe e analizza ciascuna, oppure usa un parser NDJSON |
JSON.parse is not a function |
Una tua variabile oscura il JSON globale |
Rinomina la variabile; non chiamarla mai JSON |
Le prime due meritano uno sguardo più attento, perché nessuna delle due significa "il tuo JSON è sbagliato" — significano "quello che hai ricevuto non è quello che pensi".
2. Tre sorgenti comuni di un errore a posizione 0
Una posizione 0 significa che il primo carattere stesso è illegale. Se nulla sembra sospetto, il carattere è probabilmente invisibile. Tre sospeetti abituali:
Primo: <, cioè HTML. È l'errore di parsing più comune in produzione. Un URL sbagliato, una sessione scaduta reindirizzata dal gateway, o un template di errore del server — il corpo inizia con <!DOCTYPE html> e il parser si ferma al primo carattere. La mossa corretta è aprire il pannello Network e leggere la risposta grezza, poi correggere la chiamata API, non il JSON.
Secondo: un BOM o caratteri a larghezza zero. I file salvati dal Blocco note di Windows iniziano spesso con un BOM UTF-8 (\uFEFF), e il testo copiato da pagine web o app di chat può portare spazi a larghezza zero (\u200B–\u200D). Invisibili a te, ovvi per il parser:
// Strip BOM and zero-width characters before parsing
const cleaned = raw.replace(/^\uFEFF/, '').replace(/[\u200B-\u200D]/g, '');
const data = JSON.parse(cleaned);
Terzo: il tipo sbagliato. JSON.parse(undefined) riporta "undefined" is not valid JSON; JSON.parse(someObject) riporta Unexpected token o (l'oggetto è stato convertito in "[object Object]", e o è illegale alla posizione 1). Entrambi significano "i dati sono già analizzati" oppure "non ci sono mai stati dati". Controlla il tipo, non la sintassi:
let data = text;
if (typeof data === 'string') {
data = JSON.parse(data); // Parse only when it really is a string
}
3. La posizione indica la valle; la causa è a monte
Due errori ti ingannano sulla posizione, e sono le due voci più fraintese della tabella:
- Una virgola mancante:
{"a": 1 "b": 2}riportaExpected ',' or '}' after property valuesulla riga di"b". Il resoconto è corretto, ma la correzione spetta alla fine della riga precedente. - Una parentesi di chiusura mancante: un annidamento profondo a cui manca un
}o un]fa inghiottire al parser tutto fino alla fine dell'input e riportaUnexpected end of JSON input. La posizione è la fine del file; la lacuna reale può essere molto prima. Cerca all'indietro il più recente{o[non chiuso — contare le coppie batte l'ispezione a occhio.
La tecnica generale è la bisezione: taglia il testo prima della posizione riportata e analizzalo da solo. Se viene analizzato, il problema è vicino alla posizione riportata; altrimenti biseziona più indietro. Il confine del primo blocco che fallisce è il punto reale dell'errore. Per i file grandi, formatta prima il documento — con l'indentazione allineata, il livello mancante è visibile a colpo d'occhio (il formattatore JSON online va bene per questo).
4. Quattro stati di "falso sano" che vengono analizzati ma si comportano male
Peggio di un errore c'è l'assenza di errore con dati sbagliati. In tutti e quattro i casi il JSON è valido e il parser è contento — il problema è la forma dei dati:
- Doppia codifica: l'intero documento è stato sottoposto due volte a
JSON.stringify, quindi il parsing restituisce una stringa, non un oggetto. Setypeof result === 'string', analizza di nuovo — ma trova e correggi la doppia serializzazione all'origine. - Le chiavi duplicate sovrascrivono in silenzio:
{"name": "Tom", "name": "Jerry"}è JSON valido, la maggior parte dei parser non si lamenta e il secondo valore vince. Questo morde quando si uniscono dati da più fonti; fai emergere il problema con un validatore JSON rigoroso prima che morda te. - NDJSON trattato come un unico documento: le API in streaming emettono un oggetto per riga; analizzare l'intero testo fallisce con
Unexpected non-whitespace character after JSON. Dividi su\ne analizza riga per riga. - Perdita silenziosa di precisione numerica: gli interi oltre
2^53 - 1(ID snowflake) tornano con le ultime cifre azzerate, senza alcun errore. Trasmetti gli ID come stringhe.
Il filo conduttore: il parser crede che tutto vada bene. Quindi quando i dati dell'API sembrano sbagliati, stampa prima i primi 80 caratteri del testo grezzo e il suo typeof — conferma la forma prima di discutere il contenuto.
5. Rendere gli errori impossibili in fase di scrittura
La tabella di ricerca è lo strumento a posteriori; la prevenzione è lo strumento a priori. Quattro abitudini intercettano la maggior parte degli errori prima che accadano:
// 1. Two checks before parsing any response
const response = await fetch('/api/users');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: the API returned no data`);
}
const contentType = response.headers.get('content-type') ?? '';
if (!contentType.includes('application/json')) {
throw new Error(`Expected JSON, got ${contentType}`);
}
const data = await response.json(); // 2. json() already parses — do not parse again
- Serializza per generare, non concatenare:
JSON.stringify()gestisce correttamente virgolette, a capo e caratteri di controllo; le stringhe costruite a mano sono la principale fonte diBad control charactereUnterminated string. - Cattura sempre: un errore di
JSON.parsesollevato è un crash sincrono a meno che qualcosa lo catturi. Per input non fidati — localStorage, file esterni — il blocco catch ha bisogno di un valore predefinito o di una segnalazione esplicita dell'errore. - Delega la struttura allo Schema: sintassi valida non significa struttura valida. Campi mancanti e tipi errati appartengono alla validazione JSON Schema al confine; vedi cosa risolve JSON Schema.
6. Il percorso decisionale rapido
Riduci l'intero articolo a un unico ordine decisionale. Quando vedi un errore, prendi prima la posizione e il token:
- Posizione 0 → controlla le tre sorgenti:
<(HTML), BOM, tipo errato; end of input→ controlla un corpo vuoto o troncato, poi cerca all'indietro le parentesi non chiuse;Expected ...→ guarda il carattere precedente; di solito è una virgola o una virgoletta mancante;after JSON data→ sono stati concatenati più documenti; dividi per riga;- Viene analizzato ma i dati sembrano sbagliati → esegui i quattro controlli di "falso sano".
Insieme al triage passo passo di come correggere gli errori di parsing JSON, il 90% dei problemi di parsing si risolve in cinque minuti. Tieni a portata di mano il testo dell'errore stesso — è il log di debug che il parser ha scritto per te, la sua formulazione cambia una volta ogni tre anni, e una ricerca vale un anno.
Cosa significa "Unexpected token in JSON"?
Il parser ha incontrato un carattere illegale in quel punto della grammatica JSON. Il token è il carattere rifiutato: < di solito significa che l'API ha restituito HTML, ' significa apici singoli, / significa un commento, e una lettera semplice di solito indica una chiave senza virgolette o un letterale solo JavaScript come undefined o NaN. Leggi prima il token, poi la posizione, e la causa si riduce a una.
Come correggo "Unexpected end of JSON input"?
Due sorgenti: input vuoto (un corpo di risposta vuoto, o una stringa vuota in localStorage) oppure input troncato (un download interrotto, una copia priva dell'ultima riga, un limite di dimensione). Gestisci il caso vuoto con if (!text) return; poi verifica la completezza e chiudi il più recente {, [ o " non chiuso. Nota che l'errore può anche derivare da una parentesi mancante in profondità — la posizione capita semplicemente alla fine del file.
Perché Chrome, Firefox e Safari riportano errori diversi?
I tre browser montano engine JS diversi (V8, SpiderMonkey, JavaScriptCore), e ciascuno formula i propri errori a modo suo; MDN documenta tutte le varianti ufficiali. Ma tutti e tre gli errori portano gli stessi tre elementi — posizione, aspettativa, realtà — con semantica uno a uno. Traduci nella formulazione V8 e usa questa tabella così com'è.
La posizione dell'errore indica un punto che sembra a posto — e ora?
Il vero errore è precedente. Casi tipici: una virgola mancante (riportata sulla riga successiva) e una parentesi di chiusura mancante (riportata a fine file). Risali dalla posizione riportata token per token, oppure biseziona: analizza da sola la prima metà, e il confine del primo blocco che fallisce è il punto reale dell'errore.