SyntaxError: Unexpected end of JSON input significa che il parser è arrivato alla fine della stringa prima che la struttura JSON fosse completa. I dati sono stati tagliati. Questo articolo mostra ogni modo comune in cui succede e come correggere ciascuno.
Cosa significa l'errore
JSON.parse() è una macchina a stati. Legge i caratteri uno alla volta tenendo traccia di parentesi, graffe e delimitatori di stringa aperti. Quando arriva alla fine dell'input mentre è ancora „dentro“ qualcosa —— un oggetto, un array o una stringa —— lancia:
SyntaxError: Unexpected end of JSON inputL'errore non fornisce numero di riga né posizione perché il problema è l'assenza di contenuto —— non c'è nulla da indicare.
Causa 1 —— Risposta API troncata
La causa più comune nel mondo reale. Il server ha inviato un body JSON grande e o la rete ha chiuso la connessione presto, o la risposta è stata letta prima della fine, o si è raggiunto un limite di buffering di un proxy o CDN.
// Cosa è arrivato (connessione caduta a metà risposta):
'{"users":[{"id":1,"name":"Ada"},{"id":2,"na'
JSON.parse('{"users":[{"id":1,...') // SyntaxError: Unexpected end of JSON inputCorrezione: Controlla il codice HTTP e l'header Content-Length. Logga la lunghezza del body grezzo prima del parsing. Se usi fetch, fai sempre await su response.json() invece di leggere response.text() e parsare a mano —— il parser JSON integrato del browser dà un errore più chiaro in caso di troncamento.
// Corretto
const data = await response.json();
// Fragile —— nasconde gli errori di troncamento
const text = await response.text();
const data = JSON.parse(text);Causa 2 —— Oggetto o array non chiuso
Il JSON è stato scritto a mano o generato da codice che ha dimenticato una parentesi o una graffa di chiusura.
JSON.parse('{"name":"Ada","plan":"pro"')
// Manca la } di chiusura
// SyntaxError: Unexpected end of JSON input
JSON.parse('[1, 2, 3')
// Manca la ] di chiusura
// SyntaxError: Unexpected end of JSON inputCorrezione: Usa un linter JSON o incolla la stringa in JSON Fix —— identifica il delimitatore non chiuso e, in modalità tollerante, può aggiungere automaticamente la parentesi mancante.
Causa 3 —— Stringa non chiusa
Un valore stringa che non è mai stato terminato con la virgoletta doppia di chiusura, spesso perché il valore stesso conteneva una virgoletta doppia non escapata:
JSON.parse('{"title":"He said "hello" to her"}')
// ^ la virgoletta non escapata chiude la stringa in anticipo
// SyntaxError: Unexpected end of JSON input
// Corretto —— escapa le virgolette interne con la barra rovesciata:
JSON.parse('{"title":"He said \"hello\" to her"}')Correzione: Escapa le virgolette doppie interne come \", o usa JSON.stringify() per costruire il JSON dall'inizio invece di assemblare stringhe a mano.
Causa 4 —— Stringa vuota
Passare una stringa vuota o di soli spazi a JSON.parse() lancia lo stesso errore —— non c'è proprio nulla da parsare.
JSON.parse('') // SyntaxError: Unexpected end of JSON input
JSON.parse(' ') // SyntaxError: Unexpected end of JSON input
JSON.parse() // SyntaxError: Unexpected token u… (undefined castato a stringa)Succede spesso quando un campo modulo, una chiave localStorage o una variabile d'ambiente è vuota.
// Guardia prima del parsing
const raw = localStorage.getItem('session');
if (!raw) return null;
return JSON.parse(raw);Causa 5 —— Risposta in streaming letta troppo presto
Consumando un'API in streaming o un WebSocket, è facile provare a parsare un chunk prima che il messaggio completo sia arrivato.
// ❌ Tentativo di parsare un chunk incompleto
ws.onmessage = (event) => {
const data = JSON.parse(event.data); // potrebbe essere parziale
};
// ✓ Buffer fino al confine del messaggio (framing a livello applicativo)
let buffer = '';
ws.onmessage = (event) => {
buffer += event.data;
if (buffer.endsWith('\n')) { // o controlla un delimitatore noto
const data = JSON.parse(buffer.trim());
buffer = '';
}
};Diagnosticare il troncamento: Content-Length e il reader in streaming
Due tecniche concrete per confermare se la risposta è stata davvero tagliata:
- Confronta con
Content-Length. Se il server lo ha impostato, puoi rilevare una lettura corta direttamente:const res = await fetch(url); const expected = Number(res.headers.get('Content-Length') ?? NaN); const text = await res.text(); if (Number.isFinite(expected) && text.length !== expected) { throw new Error(`truncated: got ${text.length} of ${expected} bytes`); }Nota:
Content-Lengthpuò essere assente per risposte chunked/compresse. - Leggi con il body reader in streaming. Usare
res.body.getReader()ti permette di osservare l'arrivo chunk per chunk e accorgerti quando lo stream si chiude a metà payload —— il sintomo di una connessione caduta o di un timeout del proxy. Il browser fa emergere il fallimento di rete sottostante come un reject difetchse lo stream aborta; combinalo con l'errore del parser per averne conferma.
Checklist rapida di diagnosi
- Logga
typeof inputeinput.lengthsubito prima della chiamata a parse. - Se la lunghezza sembra troppo corta, la risposta è stata troncata —— controlla i log di rete.
- Se la lunghezza è 0, la sorgente (API, storage, variabile d'ambiente) non ha restituito nulla —— aggiungi una guardia.
- Se la lunghezza sembra giusta, incolla la stringa in JSON Fix per trovare il problema strutturale.
Recupera con grazia in produzione
function safeParse(text, fallback = null) {
if (!text || !text.trim()) return fallback;
try {
return JSON.parse(text);
} catch {
console.error('JSON parse failed, input length:', text.length);
return fallback;
}
}Domande frequenti
Cosa causa „Unexpected end of JSON input“?
Il parser è arrivato alla fine della stringa mentre era ancora dentro un oggetto, array o stringa —— i dati erano incompleti. La causa più comune nel mondo reale è una risposta API troncata; altre sono una parentesi non chiusa, una stringa non terminata, una stringa vuota.
Perché non c'è un numero di riga o di posizione?
Perché il problema è contenuto mancante, non un carattere sbagliato. Non c'è nulla che il parser possa indicare —— ha semplicemente finito l'input prima che la struttura si chiudesse.
Come lo correggo per una stringa vuota?
Metti una guardia prima del parsing: if (!raw || !raw.trim()) return fallback;. Campi modulo vuoti, chiavi localStorage mancanti e variabili d'ambiente non impostate sono le sorgenti tipiche.
Come lo gestisco con grazia in produzione?
Avvolgi JSON.parse() in un helper safeParse che restituisca un fallback in caso di fallimento (vedi lo snippet sopra), e logga la lunghezza dell'input per distinguere il troncamento da una struttura malformata. Per il set completo dei pattern vedi gestire JSON rotto in JavaScript.
Ripara JSON troncato nel tuo browser
Hai una stringa JSON rotta da ispezionare o riparare? JSON Fix su fixjson.org parsa, valida e auto-ripara gli errori strutturali comuni —— parentesi mancanti incluse —— direttamente nel browser, senza inviare dati a nessun server.
- JSON Fix —— ripara e formatta JSON non valido
- Correggere „[object Object] is not valid JSON“ —— la guida completa agli errori di sintassi JSON
- Errori Unexpected Token spiegati —— la guida compagna per errori di parse a livello di token
- Gestire JSON rotto in JavaScript —— pattern per catturare e ripristinare da tutti gli errori di parse