---
type: errors
language: javascript
slug: unexpected-token
title: "SyntaxError: Unexpected token"
title_tag: "SyntaxError: Unexpected token の原因と直し方"
summary: >
  構文として読めなかったときに出ます。エラーの位置は壊れた場所ではなく気づいた場所です。
  JSON.parse で出る場合が特に多く、その見分け方と直し方までまとめています。
description: >
  括弧の閉じ忘れと JSON.parse の失敗が二大原因です。エラーの位置の読み方、JavaScript では書けて JSON では書けないものの一覧、処理系ごとの文言の違いまで扱います。
status: published
difficulty: 2
minutes: 9

versions:
  verified: "Node 22.22.3"
  since: null
  deprecated: null
  removed: null

sources:
  - title: "Error Handling and Language Extensions — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-error-handling-and-language-extensions"
  - title: "JSON.parse — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-json.parse"
  - title: "SyntaxError — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError"

terms: [構文解析, JSON, パース]

links:
  related:
    - javascript/errors/is-not-a-function
    - javascript/errors/cannot-read-properties-of-undefined
    - javascript/reference/json/parse
    - javascript/errors/unexpected-end-of-json

content_updated_at: 2026-09-07
published_at: 2026-09-07
---

**そこまで読んだところで、続きが構文として成り立たなくなった**ときに出ます。

```js bad
const class = 1;
```
```output
SyntaxError: Unexpected token 'class'
```

ほかのエラーと違い、**1行も実行されません。** 読み込む段階で止まります。
だから `console.log()` を仕込んでも[bad:何も出ません]。

## エラーの位置は「気づいた場所」

**壊れている場所とは限りません。** ここを取り違えると、正しい行をいくら見ても直りません。

```js bad
const o = { a: 1 b: 2 };

console.log(o);
```
```output
SyntaxError: Unexpected identifier 'b'
```

`b` は悪くありません。**`1` の後ろにカンマが無い**のが原因です。
処理系は `b` まで読んで初めて「おかしい」と気づきました。

**エラーが指す位置の[num:1]つ手前を見てください。**

| エラーが指すもの | 実際に見る場所 |
|---|---|
| `Unexpected identifier 'b'` | `b` の**手前**（カンマ・演算子の抜け） |
| `Unexpected token ')'` | 対応する `(` の中身 |
| `Unexpected end of input` | **どこかの閉じ忘れ**（ファイル末尾まで読み切った） |

## 原因1: 括弧や引用符の閉じ忘れ

```js bad
console.log('a'
```
```output
SyntaxError: missing ) after argument list
```

閉じ忘れは、**そこではなく[key:ずっと後ろ]で気づかれます。**
ファイルの最後まで読み切ってしまうと `Unexpected end of input` になります。

**エディタの対応括弧の色分けを使ってください。** 目で数えるより速く確実です。

## 原因2: JSON.parse に JSON でないものを渡した

**実務でいちばん多いのがこれです。** 同じ `SyntaxError` ですが、原因が全く違います。

```js bad
console.log(JSON.parse("{'a':1}"));
```
```output
SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
```

JSON は[key:二重引用符しか許しません]。`'a'` は JSON ではありません。

```js bad
console.log(JSON.parse('{"a":1,}'));
```
```output
SyntaxError: Expected double-quoted property name in JSON at position 7 (line 1 column 8)
```

**JSON に末尾のカンマは書けません。** JavaScript のオブジェクトリテラルとは違います。

```js bad
console.log(JSON.parse(''));
```
```output
SyntaxError: Unexpected end of JSON input
```

空文字も JSON ではありません。**応答が空だったときにこれが出ます。**

| JavaScript では書ける | JSON では書けない |
|---|---|
| `{ 'a': 1 }` | [bad:単引用符] |
| `{ a: 1 }` | [bad:引用符なしのキー] |
| `{ "a": 1, }` | [bad:末尾のカンマ] |
| `// コメント` | [bad:コメント] |
| `{ a: undefined }` | [bad:undefined] |

### 「`Unexpected token '<'`」が出たら

**JSON のつもりで HTML を受け取っています。** API が 404 や 500 を返し、
エラーページの HTML が来ているのがほとんどです。

```js bad
console.log(JSON.parse('<!DOCTYPE html>'));
```
```output
SyntaxError: Unexpected token '<', "<!DOCTYPE html>" is not valid JSON
```

**`<` は「HTML が返ってきた」という合図です。** JSON の書き方を直しても解決しません。

### 直しかた

**中身を見てから解析します。**

```js run
function parseJson(text) {
  try {
    return { ok: true, data: JSON.parse(text) };
  } catch (e) {
    return { ok: false, reason: e.message, head: text.slice(0, 20) };
  }
}

for (const t of ['{"a":1}', '<!DOCTYPE html><html>...', '']) {
  const r = parseJson(t);
  console.log(r.ok ? 'OK' : 'NG', '|', r.ok ? '解析できた' : r.reason);
  if (!r.ok) console.log('   受け取ったもの:', JSON.stringify(r.head));
}
```
```output
OK | 解析できた
NG | Unexpected token '<', "<!DOCTYPE "... is not valid JSON
   受け取ったもの: "<!DOCTYPE html><html"
NG | Unexpected end of JSON input
   受け取ったもの: ""
```

**受け取ったものの先頭を出せば、何が返ってきたのかすぐ分かります。**
`<!DOCTYPE` が見えた時点で、JSON の書き方を疑う必要はありません。

通信の場合は、解析する前に[key:状態コードと Content-Type]を見てください。

```js
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();
```

[dim:この環境では通信できないので、上は実行していません。形だけ示しています。]

## 原因3: 環境が対応していない書き方

新しい構文を古い処理系で読むと、**構文として読めません。**

```js run
console.log([1, 2, 3].at(-1));
console.log({ a: 1 }?.a);
```
```output
3
1
```

ここでは動きますが、`?.` は ES2020、`at()` は ES2022 です。
古いブラウザや古い Node では `Unexpected token '.'` などになります。

**「自分の環境では動くのに、相手の環境で構文エラー」はこれです。**
`node -v` と、実際に読み込んでいる環境の版を確かめてください。

## 原因4: 読み込み方が合っていない

`import` / `export` は[key:モジュールとして読み込まれたとき]だけ書けます。

```
SyntaxError: Cannot use import statement outside a module
```

- 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` |

[dim:このページの実行結果は Node 22.22.3 のものです。文言は版によっても変わります。]

## 探しかたの順序

1. **エラーの位置の[num:1]つ手前を見る。** そこが壊れている
2. `JSON` の文字があるか見る。あれば **`JSON.parse` に渡したもの**を疑う
3. `'<'` があれば **HTML が返ってきている**。通信を疑う
4. 括弧・引用符の対応をエディタの色分けで見る
5. それでも分からなければ、**半分に切って試す**。どちらで出るかで場所が絞れる

```js run
const broken = '{"a":1,}';

console.log(broken.length);

try {
  JSON.parse(broken);
} catch (e) {
  const m = e.message.match(/position (\d+)/);
  const at = m ? Number(m[1]) : -1;
  console.log('位置', at, '→', JSON.stringify(broken.slice(Math.max(0, at - 3), at + 3)));
}
```
```output
8
位置 7 → ":1,}"
```

`position` が出ているときは、**その前後を切り出す**と原因がすぐ見えます。

JSON そのものの決まり（何が消え、何が例外になるか）はこちらです。
→ [JSON.parse() と JSON.stringify()](/ja/javascript/reference/json/parse/)

読み込んだ文字列を安全に扱う形（`try` で囲んで失敗を返す）は、JSON のページに実例があります。
→ [文字列を数値に変換する](/ja/javascript/how-to/string/to-number/)
