Stai fissando uno stack trace rosso: SyntaxError: Unexpected token '<', "..." is not valid JSON. O magari è Unexpected token u in JSON at position 0. In entrambi i casi JSON.parse() si è rifiutato di girare e il tuo codice ha smesso di funzionare. Questa guida spiega esattamente cosa significa ciascuna variante di questo errore, perché succede, e come risolvere —— in fretta.
Come appare davvero l'errore
Il testo varia in base all'engine JavaScript, ma significano tutti la stessa cosa: il parser ha incontrato un carattere che non si aspettava in una posizione specifica della tua stringa.
// V8 (Chrome, Node.js, Edge)
SyntaxError: Unexpected token '<', "<html>..." is not valid JSON
SyntaxError: Unexpected token 'u', "undefined" is not valid JSON
SyntaxError: Unexpected token u in JSON at position 0 // V8 più vecchio
SyntaxError: Expected ',' or '}' after property value in JSON at position 42
// Firefox (SpiderMonkey)
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data
// Safari (JavaScriptCore)
SyntaxError: JSON Parse error: Unexpected identifier "undefined"
SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSONL'informazione chiave è sempre in due parti: quale carattere era inatteso e dove. Il carattere ti dice cosa il parser ha effettivamente ricevuto; la posizione ti dice dove guardare nella stringa.
Causa 1: il server ha restituito HTML invece di JSON
È la causa più comune di Unexpected token '<'. La tua fetch o chiamata AJAX ha ricevuto una pagina HTML —— di solito una pagina 404, un redirect di login, o un errore del server —— invece del JSON atteso. Il < è l'apertura di <!DOCTYPE html> o <html>.
// ❌ Questo crasha con "Unexpected token '<'"
const res = await fetch('/api/user');
const data = await res.json(); // il server ha restituito HTML 404
// ✅ Controlla prima lo status della risposta
const res = await fetch('/api/user');
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
const data = await res.json(); Controlla sempre res.ok (o res.status) prima di chiamare res.json(). Puoi anche ispezionare prima il testo grezzo della risposta:
const text = await res.text();
console.log(text.slice(0, 200)); // vedi cosa hai davvero ricevuto
const data = JSON.parse(text);Causa 2: il valore è undefined
Unexpected token 'u' in posizione 0 significa quasi sempre che hai chiamato JSON.parse(undefined). La stringa "undefined" inizia con la lettera u, che non è un carattere di inizio JSON valido.
// ❌ la variabile non è mai stata assegnata
const raw = localStorage.getItem('settings'); // restituisce null se mancante
JSON.parse(raw); // null va bene, ma se raw fosse undefined in qualche modo...
// ❌ dati async non ancora caricati
JSON.parse(this.state.data); // data è undefined al primo render
// ✅ Guard prima di parsare
if (raw) {
const data = JSON.parse(raw);
} Nota che localStorage.getItem() restituisce null (non undefined) per key mancanti, e JSON.parse(null) restituisce null senza errore. I soliti colpevoli sono variabili di state non inizializzate o un argomento di funzione mancante.
Causa 3: virgolette singole al posto delle doppie
// ❌ SyntaxError: Unexpected token '''
JSON.parse("{'name': 'Ada'}");
// ✅ JSON richiede virgolette doppie
JSON.parse('{"name": "Ada"}')I letterali di oggetto JavaScript accettano le virgolette singole. JSON no —— tutte le stringhe, key incluse, devono usare virgolette doppie. Capita spesso quando qualcuno serializza dati con la funzione str() di Python invece di json.dumps(), o copia un letterale di oggetto direttamente.
Causa 4: virgola finale
// ❌ SyntaxError: Unexpected token '}'
JSON.parse('{"name": "Ada", "score": 98,}');
// ^ virgola finale
// ✅
JSON.parse('{"name": "Ada", "score": 98}')JavaScript moderno permette virgole finali in array e oggetti. JSON no. I file di configurazione JSON modificati a mano sono la fonte più comune di questo errore.
Causa 5: key senza virgolette
// ❌ SyntaxError: Unexpected token 'n'
JSON.parse("{name: 'Ada'}");
// ✅
JSON.parse('{"name": "Ada"}') Le key di oggetto in JSON devono essere sempre stringhe tra virgolette doppie. Identificatori nudi come name sono validi nei letterali di oggetto JavaScript ma non in JSON.
Causa 6: commenti nel JSON
// ❌ SyntaxError: Unexpected token '/'
JSON.parse(`{
// record utente
"name": "Ada"
}`);
// ✅ Togli i commenti prima di parsare (o usa un parser JSONC)
const stripped = raw.replace(///.*$/gm, '').replace(//*[sS]*?*//g, '');
JSON.parse(stripped);JSON non ha sintassi per i commenti. I commenti vengono spesso aggiunti ai file di configurazione (il formato JSONC), ma il JSON.parse() standard li rifiuta immediatamente.
Causa 7: un BOM o carattere invisibile in posizione 0
Se l'errore dice posizione 0 ma il primo carattere visibile sembra a posto, potrebbe esserci un byte-order mark invisibile (BOM, U+FEFF) o un altro carattere di controllo davanti alla stringa —— tipico quando si legge un file salvato con codifica UTF-8-BOM su Windows.
// ✅ Togli il BOM prima di parsare
const clean = raw.replace(/^/, '');
JSON.parse(clean);Causa 8: token I o N —— Infinity e NaN
Se l'errore dice Unexpected token I o Unexpected token N, la sorgente ha prodotto Infinity, -Infinity, o NaN —— tutti validi in JavaScript ma non in JSON.
// ❌ Errore lato producer
const json = '{"ratio": NaN, "limit": Infinity}';
JSON.parse(json); // Unexpected token N (or I) ...
// ✅ Codifica deliberatamente
const safe = JSON.stringify({ ratio: NaN, limit: Infinity });
// → '{"ratio":null,"limit":null}' (nota: con perdita —— entrambi diventano null)
// ✅ Senza perdita: codifica come stringa sentinella che parsi tu
JSON.stringify({ ratio: 'NaN', limit: 'Infinity' });JSON.stringify converte silenziosamente NaN / Infinity in null. Se ti servono per il round-trip, sostituiscili con una stringa sentinella in uscita e riparsala in entrata.
Come trovare la posizione esatta dell'errore
Il messaggio di errore include un numero di posizione. Usalo per affettare la stringa e vedere esattamente cosa c'è lì:
function parseWithContext(text) {
try {
return JSON.parse(text);
} catch (err) {
// Estrai la posizione dal messaggio di errore di V8
const match = err.message.match(/position (\d+)/);
if (match) {
const pos = Number(match[1]);
const snippet = text.slice(Math.max(0, pos - 20), pos + 20);
console.error(`Error near: ..."${snippet}"...`);
console.error(` ${''.padStart(Math.min(pos, 20), ' ')}^`);
}
throw err;
}
}Domande frequenti
Cosa significa «Unexpected token in JSON»?
Significa che JSON.parse() ha incontrato un carattere non valido in quel punto della grammatica. Il token nominato ti dice cosa è stato ricevuto (< = HTML, u = undefined, ' = virgoletta singola) e la posizione ti dice dove guardare.
Perché «Unexpected token '<'» succede con fetch?
La tua richiesta ha restituito una pagina HTML —— un 404, un redirect di login, o un errore del server —— invece di JSON, e il < è il tag HTML di apertura. Controlla response.ok prima di chiamare response.json() e logga await response.text() per vedere cosa è davvero tornato.
Come risolvo «Unexpected token u in JSON at position 0»?
Hai passato undefined a JSON.parse(). Metti un guard sul valore prima (if (raw) JSON.parse(raw)) e controlla state non inizializzato o un argomento di funzione mancante. La variante strettamente collegata token o è trattata in Unexpected token o in JSON.
Come trovo la posizione esatta dell'errore?
Leggi il numero di posizione dal messaggio di errore e affetta la stringa attorno (vedi snippet sopra), o incolla il JSON in JSON Fix, che evidenzia la riga esatta del problema.
La risoluzione più rapida: incolla e ripara online
Se hai una stringa JSON rotta e devi solo aggiustarla adesso, JSON Fix gestisce tutte le cause sopra automaticamente —— virgolette singole, virgole finali, key senza virgolette, commenti, letterali Python, e altro. Incolla il tuo JSON, clicca Repair & Format, e riavrai JSON valido e pulito in un passo. Gira tutto nel tuo browser; non viene inviato nulla a nessun server.
- JSON Fix —— auto-ripara JSON rotto e mostra la riga esatta dell'errore
- Risolvere gli errori JSON Unexpected Token —— riferimento rapido per ogni variante di unexpected token
- Risolvere «[object Object] is Not Valid JSON» —— l'errore correlato quando un oggetto viene forzato a stringa prima del parsing
- JSON Diff —— confronta un JSON prima/dopo per verificare che la tua correzione non abbia cambiato nulla di inatteso