Byte order mark (BOM) breaks JSON.parse
A byte order mark is the character U+FEFF, written as the bytes EF BB BF in UTF-8. It renders as nothing at all, and RFC 8259 does not permit it at the start of a JSON document — so a file that looks flawless fails at position 0.
How the message appears
The same fault, worded by different engines. V8 (Chrome, Node, Edge) changed its format around Chrome 109, so older and newer runtimes disagree about the same document.
What causes it
A Windows editor saved as "UTF-8 with BOM"
Notepad, older Visual Studio and several Windows PowerShell redirection paths add one by default. Everything downstream reads the file correctly except the JSON parser.
Exported from a spreadsheet
Excel writes a BOM when saving UTF-8 so that it can recognise its own files later. Anything converted from such an export inherits it.
Concatenating files
Joining several UTF-8 files can leave a BOM in the middle of the result, where it is even harder to spot than at the start.
The fix
Strip a leading U+FEFF before parsing: JSON.parse(text.replace(/^\uFEFF/, "")). Better, re-save the file as UTF-8 without a BOM so the next reader does not have to.
{
"a": 1
}{
"a": 1
}The example travels in the URL fragment, which browsers never send to a server.
Worth knowing
new TextDecoder("utf-8").decode(bytes)removes a leading BOM for you unless you pass{ ignoreBOM: true }. Node’sfs.readFileSync(path, "utf8")does not — which is why the same file parses in a browser and fails in a script.- Confirm it before hunting elsewhere:
head -c 3 file.json | xxdprintsefbb bfif a BOM is present.