そこまで読んだところで、続きが構文として成り立たなくなったときに出ます。
const class = 1;const o = { a: 1 b: 2 };
console.log(o);ほかのエラーと違い、1行も実行されません。 読み込む段階で止まります。
だから console.log() を仕込んでも何も出ません。
エラーの位置は「気づいた場所」
壊れている場所とは限りません。 ここを取り違えると、正しい行をいくら見ても直りません。
console.log('a'console.log(JSON.parse("{'a':1}"));b は悪くありません。1 の後ろにカンマが無いのが原因です。
処理系は b まで読んで初めて「おかしい」と気づきました。
エラーが指す位置の1つ手前を見てください。
| エラーが指すもの | 実際に見る場所 |
|---|---|
Unexpected identifier 'b' |
b の手前(カンマ・演算子の抜け) |
Unexpected token ')' |
対応する ( の中身 |
Unexpected end of input |
どこかの閉じ忘れ(ファイル末尾まで読み切った) |
原因1: 括弧や引用符の閉じ忘れ
console.log(JSON.parse('{"a":1,}'));console.log(JSON.parse(''));閉じ忘れは、そこではなくずっと後ろで気づかれます。
ファイルの最後まで読み切ってしまうと Unexpected end of input になります。
エディタの対応括弧の色分けを使ってください。 目で数えるより速く確実です。
原因2: JSON.parse に JSON でないものを渡した
実務でいちばん多いのがこれです。 同じ SyntaxError ですが、原因が全く違います。
console.log(JSON.parse('<!DOCTYPE html>'));JSON は二重引用符しか許しません。'a' は JSON ではありません。
const res = await fetch(url);
if (!res.ok) {
throw new Error(`${res.status} ${res.statusText}`);
}
const type = res.headers.get('content-type') ?? '';
if (!type.includes('application/json')) {
throw new Error(`JSON ではありません: ${type} / ${(await res.text()).slice(0, 80)}`);
}
const data = await res.json();JSON に末尾のカンマは書けません。 JavaScript のオブジェクトリテラルとは違います。
SyntaxError: Cannot use import statement outside a module空文字も JSON ではありません。応答が空だったときにこれが出ます。
| JavaScript では書ける | JSON では書けない |
|---|---|
{ 'a': 1 } |
単引用符 |
{ a: 1 } |
引用符なしのキー |
{ "a": 1, } |
末尾のカンマ |
// コメント |
コメント |
{ a: undefined } |
undefined |
「Unexpected token '<'」が出たら
JSON のつもりで HTML を受け取っています。 API が 404 や 500 を返し、 エラーページの HTML が来ているのがほとんどです。
< は「HTML が返ってきた」という合図です。 JSON の書き方を直しても解決しません。
直しかた
中身を見てから解析します。
受け取ったものの先頭を出せば、何が返ってきたのかすぐ分かります。
<!DOCTYPE が見えた時点で、JSON の書き方を疑う必要はありません。
通信の場合は、解析する前に状態コードと Content-Typeを見てください。
この環境では通信できないので、上は実行していません。形だけ示しています。
原因3: 環境が対応していない書き方
新しい構文を古い処理系で読むと、構文として読めません。
ここでは動きますが、?. は ES2020、at() は ES2022 です。
古いブラウザや古い Node では Unexpected token '.' などになります。
「自分の環境では動くのに、相手の環境で構文エラー」はこれです。
node -v と、実際に読み込んでいる環境の版を確かめてください。
原因4: 読み込み方が合っていない
import / export はモジュールとして読み込まれたときだけ書けます。
- Node … ファイルを
.mjsにするか、package.jsonに"type": "module" - ブラウザ …
<script type="module">
.js のまま import を書いて、CommonJS として読み込まれるのがよくある形です。
処理系によって文言が違う
同じ間違いでも書いてある文が違います。自分の環境の文言で検索してください。
| 間違い | Node / Chrome(V8) | Firefox | Safari |
|---|---|---|---|
{ a: 1 b: 2 } |
Unexpected identifier 'b' |
expected , after property value |
Unexpected identifier 'b' |
| 閉じ忘れ | Unexpected end of input |
expected expression, got end of script |
Unexpected end of script |
このページの実行結果は Node 22.22.3 のものです。文言は版によっても変わります。
探しかたの順序
- エラーの位置の1つ手前を見る。 そこが壊れている
JSONの文字があるか見る。あればJSON.parseに渡したものを疑う'<'があれば HTML が返ってきている。通信を疑う- 括弧・引用符の対応をエディタの色分けで見る
- それでも分からなければ、半分に切って試す。どちらで出るかで場所が絞れる
position が出ているときは、その前後を切り出すと原因がすぐ見えます。
JSON そのものの決まり(何が消え、何が例外になるか)はこちらです。 → JSON.parse() と JSON.stringify()
読み込んだ文字列を安全に扱う形(try で囲んで失敗を返す)は、JSON のページに実例があります。
→ 文字列を数値に変換する