Un BOM interrompe il parsing JSON
In sintesi: Un BOM UTF-8 è tre byte invisibili, quindi JSON.parse fallisce sul primo carattere e riporta riga 1 colonna 1, il che fa sembrare il file vuoto o troncato.

In sintesi: controlla i primi tre byte per EF BB BF e risalva come UTF-8 senza BOM; sul server, rimuovi un U+FEFF iniziale prima di analizzare qualsiasi file caricato o di terze parti, invece di eseguire il debug del errore più tardi.
Sì — e produce il più confuso di tutti gli errori di parsing, perché il file sembra perfettamente a posto.
Cosa vedi
SyntaxError: Unexpected token in JSON at position 0
Unexpected character '\uFEFF'
Quel carattere nel messaggio è invisibile. Posizione 0 indica il primissimo byte.
cat non mostra nulla di insolito. hexdump -C file.json | head -1 sì:
00000000 ef bb bf 7b 0a 20 20 22 61 22 3a 20 31 0a 7d 0a |...{ "a": 1.}.|
7b è {. I tre byte prima sono il BOM.
Da dove vengono i BOM
Il byte order mark esisteva per UTF-16, dove l'ordine dei byte variava davvero. UTF-8 ha un unico ordine dei byte, quindi il BOM è puro overhead — eppure il Blocco note di Windows, alcune esportazioni Excel e qualche IDE più vecchio lo scrivono ancora per impostazione predefinita.
RFC 8259 è inequivocabile: il JSON scambiato tra sistemi deve essere UTF-8, e le implementazioni non devono aggiungere un BOM. I parser possono ignorare un BOM iniziale ma non sono obbligati. Browser e Node scelgono di non farlo.
Tre modi per sbarazzarsene
Salva senza BOM. In VS Code, fai clic sulla codifica nella barra di stato e scegli "Salva con codifica → UTF-8", non "UTF-8 con BOM".
Rimuovilo dalla shell.
sed -i '1s/^\xEF\xBB\xBF//' data.json
Rimuovilo in lettura. È la correzione durevole per qualsiasi cosa accetti file caricati o di terze parti:
const text = require('node:fs').readFileSync('data.json', 'utf8').replace(/^\uFEFF/, '');
JSON.parse(text);
In Python, open(path, encoding='utf-8-sig') lo gestisce automaticamente.
Due problemi simili
- Spazio a larghezza zero (U+200B) — raccolto copiando JSON da una pagina web; sintomo identico, code point diverso.
- Virgolette a larghezza piena — un IME cinese trasforma
"key"in“key”, che sembra quasi identico ma fallisce comeUnexpected token “.
Tutti e tre sono bug di caratteri invisibili. La diagnostica è sempre la stessa: esporta i primi byte in esadecimale invece di fissare il testo.
FAQ
Come posso capire se un file inizia con un BOM?
cat non mostra nulla, quindi esegui hexdump -C file.json | head -1. Se l'output inizia con ef bb bf, il file ha un BOM; in un file UTF-8 pulito dovrebbe venire prima 7b (il {).
Perché l'errore indica sempre riga 1, colonna 1?
Il BOM si trova prima di tutto il resto, quindi il primo carattere che il parser legge è U+FEFF. Il fallimento cade quindi all'inizio del file, il che fa sembrare il file vuoto.
Devo rimuovere il BOM prima del parsing?
Sì. Quando un server legge configurazioni o analizza file caricati, rimuovi prima un U+FEFF iniziale — replace(/^\uFEFF/, '') in Node, encoding='utf-8-sig' in Python — il che è molto più economico che diagnosticarlo dopo.