"Unexpected end of JSON input" — il corpo era vuoto o troncato

Questo errore significa che al parser è finito il testo prima che la struttura JSON fosse completa. Quasi sempre il corpo della risposta era vuoto, oppure il trasferimento è stato troncato — e i due casi si risolvono in modo diverso.

A differenza della maggior parte degli errori JSON, questo non nomina alcun carattere, perché non ne era rimasto nessuno da nominare. Il parser ha raggiunto la fine dell'input mentre attendeva ancora una parentesi graffa, quadra o un apice di chiusura. Il tuo codice di parsing va bene — ti è stato consegnato meno testo di quanto formi un documento JSON completo.

La causa più comune: il corpo era completamente vuoto

JSON.parse("") solleva esattamente questo errore, e una stringa vuota capita più spesso di quanto ci si aspetti. Una risposta 204 No Content non ha corpo per definizione, ed è la norma per un DELETE o un PUT riusciti. Un 304 Not Modified non restituisce nulla, perché il messaggio è proprio che la tua cache è ancora valida. Una richiesta HEAD non restituisce mai un corpo. E una richiesta fallita a livello di rete — connessione rifiutata, preflight CORS respinto, richiesta annullata — può lasciarti una stringa vuota anziché un'eccezione, a seconda del client.

La seconda causa: la risposta è stata troncata a metà strada

Qui il corpo inizia come JSON valido e semplicemente si interrompe a metà. La connessione è caduta, è scattato un timeout mentre la risposta era ancora in transito, oppure qualcosa tra te e il server ha imposto un limite di dimensione — reverse proxy, impostazioni dei buffer di nginx e tetti di risposta delle funzioni serverless lo fanno in silenzio. Un segnale utile: il troncamento tende a essere intermittente e correlato alla dimensione. Le risposte piccole funzionano, quelle grandi falliscono. Se lo stesso endpoint viene analizzato bene con un record e si rompe con mille, hai un troncamento, non un JSON malformato.

La terza causa: lettura da storage o da file

Se il JSON proviene da localStorage, da un file di cache o dal disco, potrebbe essere stata la scrittura a essere incompleta. localStorage fallisce silenziosamente appena si supera la quota, quindi un oggetto grande può restare scritto a metà senza che venga sollevata alcuna eccezione in scrittura — l'errore emerge solo dopo, in lettura. Un file scritto da un processo andato in crash, o su un disco pieno, produce lo stesso risultato. Il tratto distintivo: fallisce in modo identico ogni volta, mentre un troncamento di rete è di solito intermittente.

Come distinguerli in un solo passo

Prima di chiamare JSON.parse, stampa la lunghezza del valore grezzo e i suoi ultimi caratteri. Lunghezza zero significa corpo vuoto, e quello che dovresti fare è gestire il codice di stato invece di analizzare. Una lunghezza diversa da zero che non termina con } o ] significa troncamento, e conviene confrontare la lunghezza ricevuta con l'header Content-Length. Se la lunghezza sembra completa e fallisce comunque, il problema è altrove nella stringa e il messaggio avrebbe nominato un carattere.

La soluzione è una guardia, non un try/catch

L'istinto è avvolgere il parsing in un try/catch e andare avanti, ma questo nasconde la condizione reale e trasforma un errore chiaro in uno stato vuoto silenzioso. Controlla prima il codice di stato e gestisci 204 e 304 esplicitamente come "nessun corpo, ed è corretto". Verifica che la risposta sia davvero andata a buon fine prima di dare per scontato che ci sia qualcosa da analizzare. Un try/catch ha senso attorno a dati genuinamente inattesi e malformati, non attorno al caso perfettamente prevedibile di una risposta che non doveva mai contenere JSON.

Quando hai il testo grezzo e vuoi sapere esattamente dove smette di essere valido, incollalo nel nostro validatore JSON — indica la posizione in cui la struttura si interrompe, rendendo un troncamento immediatamente evidente. Funziona nel tuo browser, quindi puoi incollare una risposta reale di un'API senza rischi.

→ Validatore JSON