← 記事一覧

JSON の不正なエスケープ文字: 有効なエスケープと修正

JSON の不正なエスケープ文字とは、バックスラッシュの後に JSON が許さないものが続くこと。有効なエスケープの一覧と、\x、パス、\u の修正方法を示します。

SyntaxError: Bad escaped character in JSON at position N は、文字列の中にバックスラッシュ(\)があって、その直後に JSON が認識しない文字が続いていることを示します。JSON は固定された小さな集合のエスケープシーケンスしか許しません —— バックスラッシュの後にそれ以外のものが来ると、このエラーになります。許容される一覧と修正方法を以下にまとめます。

どの文字列エラーですか?

  • Bad escaped character —— \ の後に JSON が許さない文字が続く(例:\x、Windows パス)。
  • Bad control character —— 生の tab/改行/null バイトが文字列のにエスケープなしで含まれる。
  • Unterminated string —— " で始まった文字列が閉じられていない。

エラーの見え方

// V8 (Chrome / Node / Edge)
SyntaxError: Bad escaped character in JSON at position 14

// Firefox
SyntaxError: JSON.parse: bad escaped character at line 1 column 15 of the JSON data

// Safari
SyntaxError: JSON Parse error: Invalid escape character \x

JSON が許す全てのエスケープ

JSON 文字列の中で、バックスラッシュの後に来てよいのは次のいずれかだけです:

\"   ダブルクォート
\\   バックスラッシュ
\/   スラッシュ
\b   バックスペース
\f   フォームフィード
\n   改行
\r   復帰
\t   タブ
\uXXXX   Unicode コードポイント(ちょうど 4 桁の 16 進数)

\ の後にそれ以外のもの —— \x\'\a\0\Users のような Windows パス、または不完全な \u12 —— が来ると、すべて「bad escaped character」になります。

なぜ起きるか

原因 1 —— 他言語のエスケープを借用

// ❌ \x と \' は JS/Python では有効だが JSON では無効
{ "code": "\x1b[0m", "name": "O\'Brien" }

// ✅ そのバイトには \u エスケープを使い、アポストロフィにはエスケープを付けない
{ "code": "\u001b[0m", "name": "O'Brien" }

原因 2 —— Windows のファイルパス

// ❌ 各バックスラッシュが無効なエスケープを開始する
{ "path": "C:\Users\Ada\file.json" }

// ✅ すべてのバックスラッシュをエスケープ(またはスラッシュを使う)
{ "path": "C:\\Users\\Ada\\file.json" }
{ "path": "C:/Users/Ada/file.json" }

原因 3 —— 切り詰められたか壊れた \u エスケープ

// ❌ \u はちょうど 4 桁の 16 進数が必要
{ "char": "\u12" }

// ✅
{ "char": "\u0012" }

サロゲートペアと BMP 外の文字

JSON の \uXXXX エスケープは固定で 4 桁の 16 進数で、扱えるコードポイントは U+FFFF(基本多言語面 BMP)までです。それより上の文字 —— 絵文字、多くの CJK 拡張、数学記号 —— は UTF-16 サロゲートペア で書く必要があります:

// 😀 (U+1F600) をサロゲートペアで
"\uD83D\uDE00"

// 許されない —— JSON には \U も \u{...} もない
"\u1F600"     // 不正なエスケープ(最初の 4 桁だけが消費され、残りは普通のテキスト扱い)
"\u{1F600}"   // 不正なエスケープ

これはファイル自体はディスク上で UTF-8 だとしても、JSON が エンコード として UTF-16 形式を取るためです。実用上の影響は二つ:

  • ファイル中の UTF-8 は問題なし。 "😀" とそのまま書けます。現代的なパーサは扱えます。サロゲートペア形式が必要なのは、どうしてもエスケープしたいときだけです。
  • 孤立サロゲートに注意。 \uD83D の後に対応する低位サロゲートがない、あるいはその逆は、JSON 仕様上は許されますが UTF-16 としては壊れています —— 下流の消費側(特に Postgres の jsonb)は受け付けません。 JSON.stringify はきちんとしたペアしか作りません。

修正の手順

  1. 報告された位置にジャンプ して、無効な文字の直前にある \ を見つけてください。
  2. 迷子のバックスラッシュですか?(例:Windows パス)—— \\ に倍にするか、スラッシュに切り替えてください。
  3. 外来のエスケープですか \x\' のような? —— \xNN\u00NN に変換し、' の前のバックスラッシュは削除してください。
  4. 短い \u ですか? —— ちょうど 4 桁の 16 進数にパディングしてください。
  5. 最善の修正: JSON.stringify() で JSON を組み立てる。常に有効なエスケープを生成します。
// 予防 —— エスケープは自動的に正しい
JSON.stringify({ path: 'C:\\Users\\Ada', code: '\x1b[0m' });
// → {"path":"C:\\Users\\Ada","code":"\u001b[0m"}

よくある質問

「Bad escaped character in JSON」とは何ですか?

文字列内のバックスラッシュの後に、JSON が許すエスケープ(" \\ / b f n r t\uXXXX)以外の文字が続いています。よくある犯人は \x\'、それからエスケープされていない Windows パスです。

JSON に Windows パスをどう書きますか?

すべてのバックスラッシュを倍に(C:\\\\Users)して、それぞれが有効な \\ エスケープになるようにするか、JSON が受け付けるスラッシュ(C:/Users)を使ってください。

「Bad control character」と同じですか?

いいえ。「Bad escaped character」はバックスラッシュの後の無効な並びについてです。「bad control character」 は、バックスラッシュなしで生の制御バイト(tab、改行)がそのまま入っていることについてです。

今すぐ直す