JSONが読み込めない・整形できない原因と対処法|エラーメッセージの読み方
APIのレスポンスや設定ファイルを開いたら、パーサーがエラーを吐いて読み込めない。JSONで最も多いトラブルです。原因は毎回だいたい同じ数パターンに収まるため、チェックする順番さえ決めておけば数分で解決できます。
まずエラーメッセージを読む
多くの環境では、問題の位置が数値で示されます。
SyntaxError: Unexpected token } in JSON at position 142
この position 142 は「先頭から142バイト目」ではなく「142文字目」です。ここを見るのが最短ルートですが、エディタで142文字目を探すのは面倒です。
より実用的なのは、JSONを整形してみることです。整形ツールに通すと、パーサーが止まった位置が構造として見えるため、目視で発見しやすくなります。JSON整形・検証ツールは、パースに失敗した場合にエラー内容をそのまま表示します。
エラーメッセージの典型的なパターンと意味は次のとおりです。
| メッセージ | 意味 | 主な原因 |
|---|---|---|
Unexpected token } | 閉じ括弧が想定外の位置にある | 末尾カンマ |
Unexpected token ' | シングルクォートを検出 | 文字列がシングルクォート |
Unexpected end of JSON input | 途中で入力が終わった | 括弧の閉じ忘れ、データの切れ |
Unexpected token o in JSON at position 1 | オブジェクトを文字列化せずに渡した | [object Object] を parse している |
Unexpected non-whitespace character | 有効なJSONの後にゴミがある | 複数のJSONが連結、余分な文字 |
原因1:末尾カンマ(最頻出)
JSONでは、配列やオブジェクトの最後の要素の後にカンマを置けません。
{
"name": "テスト",
"count": 3,
}
最後の 3, のカンマが不正です。JavaScript のオブジェクトリテラルでは許容されるため、コードから手でコピーしてくると頻繁に混入します。
{
"name": "テスト",
"count": 3
}
原因2:シングルクォート
JSONの文字列は必ずダブルクォートです。 キーも同様です。
{ 'name': 'テスト' } ← 不正
{ "name": "テスト" } ← 正しい
キーをクォートなしで書くのも不正です。
{ name: "テスト" } ← 不正(JavaScript では有効)
ここが「JSONとJavaScriptオブジェクトの見た目が似ているのに互換ではない」最大の落とし穴です。JSONはJavaScriptの部分集合ではありますが、逆は成り立ちません。
原因3:コメントが書かれている
JSONの仕様にコメントは存在しません。
{
// ユーザー名
"name": "テスト"
}
これは不正です。設定ファイルとして使う際にコメントを入れたくなりますが、標準のJSONパーサーは受け付けません。
どうしてもコメントが必要な場合は、次の選択肢があります。
- JSONC(コメント付きJSON)を受け付けるツールを使う(VS Codeの設定ファイルなどが該当)
- コメント用のキーを作る(
"_comment": "説明") - 設定ファイル自体を YAML や TOML に変える
原因4:使えない値を書いている
JSONで使える値は、文字列・数値・真偽値・null・配列・オブジェクトの6種類だけです。
{
"a": undefined, ← 不正(JSONに undefined はない)
"b": NaN, ← 不正
"c": Infinity, ← 不正
"d": 'text', ← 不正
"e": 0x1F, ← 不正(16進表記は使えない)
"f": .5, ← 不正(先頭の0を省略できない)
"g": new Date() ← 不正
}
特に NaN は、プログラムで生成したJSONに混入しやすい値です。数値計算の結果が NaN になり、そのまま JSON.stringify を通すと null に変換されますが、文字列連結で自前でJSONを組み立てている場合は NaN がそのまま出力され、読み込み時にエラーになります。
原因5:見えない文字が混入している
構文的にはどこにも問題がないのにエラーになる場合、目に見えない文字を疑ってください。
BOM(Byte Order Mark)
UTF-8で保存する際、ファイル先頭に EF BB BF の3バイトが付くことがあります(BOM付きUTF-8)。Windows版のExcelやメモ帳が付けることがあり、多くのJSONパーサーはこれを不正な文字として扱います。
エラーが position 0 や position 1 を指している場合、BOMの可能性が高いです。エディタで「UTF-8(BOMなし)」を選んで保存し直してください。
全角スペース
日本語入力の状態でインデントを打つと、半角スペースではなく全角スペース(U+3000)が入ることがあります。見た目ではほぼ判別できません。
{
"name": "テスト"
}
上の例は2行目の先頭が全角スペースです。エディタで「空白文字を表示」を有効にすると確認できます。
制御文字・改行
JSONの文字列の中に、生の改行やタブを直接書くことはできません。エスケープが必要です。
{ "text": "1行目
2行目" } ← 不正
{ "text": "1行目\n2行目" } ← 正しい
APIから受け取ったテキストをそのまま埋め込むと発生しやすい問題です。
判別のしかた
見えない文字が混入しているか調べるには、文字数を数えるのが手っ取り早い方法です。 文字数カウントツールで文字数とバイト数の両方を確認すると、想定と合わない場合に混入を疑えます(全角スペースはUTF-8で3バイトを占めます)。
原因6:JSONではないものをJSONとして読んでいる
意外に多いのがこれです。
Unexpected token o in JSON at position 1
このエラーは、すでにオブジェクトになっているものを JSON.parse に渡したときの典型です。[object Object] という文字列がパースされ、2文字目の o で失敗しています。
const data = await res.json(); // すでにオブジェクト
JSON.parse(data); // ← ここでエラー
同様に、Unexpected token < は、JSONを期待した場所にHTMLが返ってきたことを意味します。APIがエラーページ(404や500のHTML)を返しているケースがほとんどです。この場合、直すべきはJSONではなくリクエスト側です。
手順としてまとめる
エラーが出たら、次の順でチェックしてください。上から順に、遭遇頻度が高い順です。
- 末尾カンマを探す
- クォートがすべてダブルクォートか確認する
- 括弧の対応が取れているか(整形ツールに通すと一目で分かります)
NaN/undefined/ コメントが含まれていないか- BOM・全角スペースを疑う(エラー位置が先頭付近なら特に)
- そもそもJSONではないものを読んでいないか
1〜3で解決しない場合は、JSONを半分に切って、どちらでエラーが出るかを見る方法が有効です。二分探索で数回繰り返せば、巨大なJSONでも問題箇所を素早く絞り込めます。
整形は「読むため」だけではない
JSON整形ツールは見た目を整えるためのものと思われがちですが、実務上の主な用途は検証です。整形が通る=構文的に正しいJSONである、という確認になります。
JSON整形・検証ツールでは、インデント幅を指定した整形と、空白を除去する圧縮(minify)の両方に対応しています。APIに送る前の検証や、レスポンスの中身の確認に使えます。
なお、当ツールはブラウザ内で処理を行うため、業務データや認証情報を含むJSONを貼り付けてもサーバーに送信されません。 オンラインのJSON整形サービスの多くはサーバーで処理するため、本番のレスポンスを貼り付けるのは避けるべきです。この点は意外と見落とされています。
まとめ
- まずエラーメッセージの位置を見る
- 末尾カンマ・シングルクォート・コメントがJSONで許されない三大要素
- 構文が正しく見えるのにエラーなら、BOM・全角スペースを疑う
Unexpected token <はJSONの問題ではなくHTMLが返ってきている- 巨大なJSONは半分に切って問題箇所を絞る
JSONのエラーは種類が限られています。この順番でチェックすれば、ほとんどの場合は数分で解決します。