メインコンテンツへスキップ

← ブログ一覧へ

よくある JSON エラーと修正方法

「Unexpected token in JSON」エラーのほとんどは、同じ短いミスのリストから生まれます。順に修正法を挙げます。(形式が初めてなら JSON とは から。)

これは私たちのツールが実際に出力したメッセージです。 壊れた 6 つの断片を JSON フォーマッターに入れ、返ってきた文字をそのまま記録しました。今あなたが見ているメッセージと突き合わせてください。

  • {"a":1,} → Expected double-quoted property name in JSON at position 7 (line 1 column 8)
  • {'a':1} と {a:1} → Expected property name or ’}’ in JSON at position 1 (line 1 column 2)
  • {"a":{"b":1} → Expected ’,’ or ’}’ after property value in JSON at position 12 (line 1 column 13)
  • {"a":undefined} → Unexpected token ‘u’, ”{“a”:undefined}” is not valid JSON
  • {"a":1 "b":2} → Expected ’,’ or ’}’ after property value in JSON at position 7

知っておくとよい点が 2 つ。シングルクォートの文字列と引用符なしのキーはまったく同じメッセージになります。パーサーがどちらも同じ位置で諦めるからです。またこの文言はブラウザ自身の JSON パーサー由来なので、Firefox や Safari では表現が異なります。頼れるのは position の数値です。行と列の注記は私たちのツールが付けています。

1. 末尾のカンマ

JSON は最後の項目の後のカンマを許しません。

{ "a": 1, "b": 2, }   ← 無効
{ "a": 1, "b": 2 }    ← 有効

2. シングルクォート

文字列とキーはダブルクォートが必須です。

{ 'name': 'Ann' }   ← 無効
{ "name": "Ann" }   ← 有効

3. クォートなしのキー

JavaScript のオブジェクトと違い、JSON のキーは必ずクォートします。

{ name: "Ann" }     ← 無効
{ "name": "Ann" }   ← 有効

4. コメント

JSON にコメントはありません。解析前に // と /* */ を削除してください。

5. 括弧の誤り・不足

すべての { に }、すべての [ に ] が必要です。よくあるのは括弧の取り違えや、複数レコードを配列 [ … ] で包み忘れることです。

括弧の不足は、報告位置が誤りから最も遠いエラーです。{"a":{"b":1} —— 閉じ括弧が 1 つ足りない —— が返すのは

✗ JSON syntax error: Expected ',' or '}' after property value in JSON at position 12 (line 1 column 13) [L1:13]

位置 12 は入力の末尾です。パーサーは読む文字が尽きて初めて何かが足りないと分かるからです。誤りは左端の開き {、報告は右端。カンマ不足の {"a":1 "b":2} と比べてください:

✗ JSON syntax error: Expected ',' or '}' after property value in JSON at position 7 (line 1 column 8) [L1:8]

同じメッセージですが、位置 7 はカンマがあるべき場所にちょうど落ちます。報告された桁がファイルの最後の文字なら、指された行を読むより、閉じていない括弧を探してください。

6. 数値でない値

NaN・Infinity・undefined は有効な JSON ではありません。数値・文字列・null を使ってください。

「数値でない」値はまた別の失敗をし、メッセージがそれを物語ります。{"a":undefined} が返すのは

✗ JSON syntax error: Unexpected token 'u', "{"a":undefined}" is not valid JSON

パーサーが桁を示さず入力全体を引用して返している点に注目してください。undefined を値として解釈し始めることすらできないため、「妥当なトークンがどこで壊れたか」という位置が存在しないのです。NaN と Infinity も同じ失敗をします。JSON が「値がない」と言う方法は null だけです。

最速の修正:検証する

目で探すより、エラー位置を示す検証ツールに貼り付けましょう。

上の 6 つを直せば、「無効な JSON」問題の大半は消えます——すべてブラウザ内で動作するので、機微なデータも外に出ません。

実例:修正前と修正後

次のデータは、上のミスを一度に 3 つ踏んでいます。

{
  'user': "Ann",
  "roles": ["admin", "editor",],
  "active": True,
}

パーサーは最初に出会った問題で停止し、Unexpected token ' at position 4 のような短いメッセージを返します——実際には 3 か所おかしいのに、です。まとめて直しましょう。シングルクォートをダブルクォートに、末尾のカンマ 2 つを削除、真偽値を小文字に:

{
  "user": "Ann",
  "roles": ["admin", "editor"],
  "active": true
}

True・False・None に注意。これは Python の書き方です。JSON が理解するのは小文字の true・false・null だけです。

JSON は JavaScript のオブジェクトではない

これらのミスの多くは、JSON を JavaScript のソースコードのように扱うことから生まれます。しかし違います——JSON は文法がより厳格なテキスト形式です。

  • キーは常にクォート付きの文字列で、裸の識別子は使えません;
  • 使えるのはまっすぐなダブルクォートだけ。シングルクォートやバッククォート、ワープロが挿入する丸い「スマートクォート」は使えません;
  • 末尾のカンマ・コメント・関数呼び出しは使えません;
  • 数値は先頭に +、先頭のゼロ、末尾だけのドットを付けられません。

可能な限り、文字列を手で貼り合わせるのではなく、本物のシリアライザで JSON を生成しましょう——JavaScript なら JSON.stringify、Python なら json.dumps。クォートとエスケープを毎回正しく処理してくれます。

よくある質問

なぜエラーが「position 0」と出るの?

入力が空、先頭に BOM(バイト順マーク)が付いている、あるいは JSON ではなく HTML のエラーページ、のいずれかです。構文を疑う前に、API が実際に何を返したか確認しましょう。

設定ファイルにコメントを残せる?

素の JSON では残せません。編集中は JSON5 や JSONC を使うか、YAML に切り替え、厳格なパーサーに渡す前に非標準の要素を取り除きます。

ファイルが大きすぎて開けないときは?

まず整形して入れ子構造を見えるようにし、不要な枝を折りたたみます。JSON 整形ツール に貼れば、その両方を一度に行えます。