DevToolBox

JSONの "Unexpected token" エラーを直す

最終更新日: 2026-07-13公開日: 2026-04-19執筆: DevToolBox編集部

JSON.parseSyntaxError: Unexpected token ... in JSON at position Nが出たときの原因を、position N の読み方から系統立てて解説します。

This guide explains why JSON.parsethrows "Unexpected token ... at position N" and walks through the most common causes (trailing commas, single quotes, undefined, BOM, NaN).

TL;DR

JSONエラーを診断

JSON文字列またはエラーメッセージから、よくある原因と修正方法を推測します。

ブラウザ内でのみ処理

入力内容の外部送信・保存は行いません。

診断結果はここに表示されます。

1. position N の読み方 / How to read "position N"

position の N は、入力文字列の 0始まりのコードポイントインデックス。 改行・タブ・BOM も 1 文字としてカウントされます。VS Code なら Ctrl+G → 目的行へジャンプし、 列番号を N から換算すれば一発で特定できます。

N is a zero-based character index, counting newlines and BOM. Jump to it in your editor.

コンソールでの見え方

APIがJSONではなくHTMLのエラーページを返すと、DevTools Consoleでは次のように表示されます。先頭の <<!DOCTYPE が、HTMLをJSONとして読もうとした証拠です。

Uncaught SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
    at JSON.parse (<anonymous>)
    at loadUser (app.js:24:18)
                         ^ 呼び出し元の行を確認
                              ^ '<!DOCTYPE' はHTMLが返った証拠

// Networkタブでも Content-Type と本文を確認する
// 想定: application/json
// 実際: text/html

この場合、JSON文字列の修正だけでは解決しません。Networkタブでステータスコード、Content-Type、レスポンス本文を確認し、APIのURL間違い、認証切れ、サーバー側のエラーページなどを直します。response.json() の前に response.ok を確認するのも有効です。

2. 代表的な原因と対処 / Common causes

症状 / Symptom原因 / Cause対処 / Fix
Unexpected token , in JSON at position N末尾カンマ / Trailing comma最後のカンマを削除 / Remove it
Unexpected token ' in JSONシングルクォート / Single quotes全てダブルクォートに / Use double quotes
Unexpected token u in JSON at position 0値が undefined / Value is undefinedresponse ?? "null" で fallback
Unexpected token in JSON at position 0 (不可視)BOM / UTF-8 BOMs.replace(/^\uFEFF/, "")
Unexpected token N in JSONNaN / Infinity を書いた / Non-JSON numbersnull に置換 / Replace with null
Unexpected end of JSON input閉じ括弧不足 / Truncatedログ切れなら再取得 / Re-fetch source

3. JavaScript値に起因する周辺パターン

localStorage.getItem() が null を返す

キーが存在しないと localStorage.getItem() は文字列ではなく null を返します。現代のブラウザでは JSON.parse(null)null になりますが、値がないことを設定オブジェクトと取り違えると後続処理で失敗します。明示的に存在確認し、初期値を決めてください。

const stored = localStorage.getItem("preferences");
const preferences = stored === null
  ? { theme: "system" }
  : JSON.parse(stored);

Date オブジェクトを JSON.parse に渡す

JSON.parse が受け取るのはJSON文字列です。Dateオブジェクトを渡すと文字列化された日付をJSONとして解釈しようとしてエラーになります。Dateを保存するなら、先にオブジェクト全体を JSON.stringify し、復元後に日付文字列からDateを作り直します。

const text = JSON.stringify({ createdAt: new Date().toISOString() });
const data = JSON.parse(text);
const createdAt = new Date(data.createdAt);

4. JSON Schema と Ajv で再発を防ぐ

パースできるJSONでも、必須項目の欠落や型違いまでは JSON.parse で検出できません。すでにAjvを利用するプロジェクトでは、パース後の値をJSON Schemaで検証すると、想定外のデータを業務処理へ渡す前に止められます。Ajv自体は不正なJSON文字列をパースするものではないため、JSON.parse の例外処理と組み合わせます。

import Ajv from "ajv";

const ajv = new Ajv();
const validate = ajv.compile({
  type: "object",
  properties: { id: { type: "integer" }, name: { type: "string" } },
  required: ["id", "name"],
  additionalProperties: false,
});

try {
  const data: unknown = JSON.parse(responseText);
  if (!validate(data)) {
    console.error("Schema validation failed", validate.errors);
  }
} catch (error) {
  console.error("Invalid JSON", error);
}

APIの送信側と受信側で同じスキーマを契約として管理すると、形式変更をテスト段階で検知しやすくなります。Ajvを未導入のプロジェクトでは、要件と既存構成を確認してから採用してください。本記事のために依存を追加する必要はありません。

5. 再発防止 / Prevention

外部APIを読む場合は、まずHTTPステータスと Content-Type を検査し、その後にパースします。ログへ本文全体を出すと個人情報やトークンが漏れる可能性があるため、必要な範囲だけを安全に記録してください。

6. English summary

JSON.parse throws Unexpected token ... in JSON at position Nwhen the input contains something that isn't legal JSON. The position is a zero-based character index, counting newlines and BOM. The frequent offenders are trailing commas, single quotes, a literalundefined, a UTF-8 BOM at position 0, and NaN/Infinitywhich JSON doesn't allow. Jump to the index in your editor, identify the category, and apply the corresponding fix. For recurring issues, validate payloads with a JSON Schema.

関連ツール / Related tools

関連ガイド / Related guides