JSON Toolkit

BOM は JSON のパースを壊すか

要点:UTF-8 BOM は見えない 3 バイトなので、`JSON.parse` が最初の文字で失敗し、1 行 1 列目を報告します。そのためファイルが空や途中切れに見えます。

初級約 4 分で読めます2026-10-30 公開2026-10-30 更新
BOM が JSON のパースを壊す仕組みと除去方法

要点:先頭 3 バイトが EF BB BF かを確認し、BOM なしの UTF-8 で再保存しましょう。サーバーでは、アップロードやサードパーティのファイルをパースする前に先頭の U+FEFF を除去し、後で失敗をデバッグしないようにします。

壊します。しかもファイルが完全に正常に見えるため、すべてのパースエラーの中で最も混乱を招くものを生みます。

見えるもの

SyntaxError: Unexpected token  in JSON at position 0
Unexpected character '\uFEFF'

メッセージ内のその文字は見えません。position 0 は最初のバイトを意味します。

cat は何も異常を示しません。hexdump -C file.json | head -1 は示します。

00000000  ef bb bf 7b 0a 20 20 22  61 22 3a 20 31 0a 7d 0a  |...{  "a": 1.}.|

7b は { です。その前の 3 バイトが BOM です。

BOM はどこから来るか

バイトオーダーマークは UTF-16 のために存在し、そこではバイト順が実際に変わりました。UTF-8 は単一のバイト順なので、BOM は純粋なオーバーヘッドです。それでも Windows のメモ帳、一部の Excel エクスポート、いくつかの古い IDE は今も既定で書き込みます。

RFC 8259 は曖昧ではありません。システム間で交換する JSON は UTF-8 でなければならず、実装は BOM を付けてはなりません。パーサーは先頭 BOM を無視してもよいが、必須ではありません。ブラウザと Node は無視しないことを選んでいます。

除去する三つの方法

BOM なしで保存する。 VS Code ではステータスバーのエンコーディングをクリックし、「エンコーディング付きで保存 → UTF-8」を選びます。「UTF-8 with BOM」ではありません。

シェルで除去する。

sed -i '1s/^\xEF\xBB\xBF//' data.json

読み取り時に除去する。 アップロードやサードパーティのファイルを受け入れるものには、これが持続的な修正です。

const text = require('node:fs').readFileSync('data.json', 'utf8').replace(/^\uFEFF/, '');
JSON.parse(text);

Python では open(path, encoding='utf-8-sig') が自動で扱います。

似た二つの問題

  • ゼロ幅スペース(U+200B):Web ページから JSON をコピーするときに混入します。症状は同じでコードポイントが違います。
  • 全角引用符:日本語入力が "key" を “key” に変え、ほとんど同じに見えるのに Unexpected token “ で失敗します。

三つとも不可視文字のバグです。診断は常に同じで、テキストを見つめるのではなく先頭バイトを 16 進で出力します。

FAQ

ファイルが BOM で始まるかを見分けるには?

cat は何も示さないので、hexdump -C file.json | head -1 を実行します。出力が ef bb bf で始まれば BOM があり、きれいな UTF-8 ファイルでは 7b({)が先頭に来るはずです。

エラーが常に 1 行 1 列目を指すのはなぜですか?

BOM が他のすべての前に座るので、パーサーが最初に読む文字が U+FEFF です。失敗はファイル先頭に着地し、ファイルが空に見えます。

パース前に BOM を除去すべきですか?

はい。サーバーが設定を読むときやアップロードファイルをパースするときは、先頭の U+FEFF を除去します。Node なら replace(/^\uFEFF/, '')、Python なら encoding='utf-8-sig'。後で診断するよりずっと安上がりです。

さらに読む