SyntaxError: Unexpected token 'u', "undefined" is not valid JSON(古いエンジン:Unexpected token u in JSON at position 0)はほぼ常に JSON.parse(undefined) を呼んだことを意味します。JavaScript は undefined をテキスト "undefined" に文字列化し、パーサは先頭の u で詰まります。理由と直し方は以下の通り。
エラーの見た目
// V8 (Chrome / Node / Edge)
SyntaxError: "undefined" is not valid JSON
SyntaxError: Unexpected token 'u', "undefined" is not valid JSON
SyntaxError: Unexpected token u in JSON at position 0 // 古い V8
// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 1
// Safari
SyntaxError: JSON Parse error: Unexpected identifier "undefined" 位置 0 の u は文字列 "undefined" の最初の文字 —— パーサは実データを受け取らなかったのです。
なぜ起こるか:undefined をパースした
JSON.parse() は引数をまず文字列に強制します。undefined を渡すと、リテラル文字列 "undefined" をパースしますが、これは有効な JSON ではありません。値が undefined になる典型的な理由:
- 変数や関数引数が一度も代入されていない
- オブジェクトのプロパティが存在しない(タイポや構造違い):
obj.missing - async な値がまだ準備できていない(
awaitの前にパースした) returnのない関数をソースとして使った
壊れた例
const cached = localStorage.getItem('settings'); // キー欠落 → null、OK
const draft = window.appState?.draft; // プロパティ欠落 → undefined
const data = JSON.parse(draft); // ❌ "undefined" is not valid JSON修正例
// パース前にガード
const data = draft ? JSON.parse(draft) : null;
// または安全なヘルパ
function safeParse(text, fallback = null) {
if (typeof text !== 'string' || text.trim() === '') return fallback;
try { return JSON.parse(text); } catch { return fallback; }
}
const data2 = safeParse(draft); 注意:JSON.parse(null) は 投げません —— null を返します。そして localStorage.getItem() は欠落キーに対して null(undefined ではなく)を返します。なので u エラーは undefined の値を指す、ストレージのキー欠落ではない。
SyntaxError vs TypeError:なぜ こちら になるか
細かいが有用な点:JSON.parse(undefined) は SyntaxError を投げます。TypeError ではありません。なぜ?仕様では JSON.parse はまず引数を 文字列に強制("undefined")し、その文字列をパースするから。エラーは「この文字列は有効な JSON でない」であって「型が違う」ではない。だから JSON.parse(undefined) と JSON.parse("undefined") は同じ「position 0」メッセージを出すのです。
対照的に型チェックを 行う API:JSON.stringify(BigInt(1)) → TypeError、JSON.parse(Symbol()) → TypeError(Symbol は文字列化できない)。パースエラーを捕まえるなら err instanceof SyntaxError で絞り込み、悪いデータ と 悪い引数 を分けて扱う。
直し方 —— ステップごとに
- 入力をログする:
console.log(typeof src, src)をパース直前に。undefinedと出れば犯人。 - セットされるはずの場所を辿る —— 未初期化の state フィールド、欠けた引数、またはオブジェクトに存在しないプロパティ。
- ガードを追加(
if (src))またはsafeParseフォールバックで、欠落した値がJSON.parse()に届かないようにする。 - async の場合、パース前に値を
awaitすることを確認。
よくある質問
「Unexpected token u in JSON at position 0」はどういう意味?
undefined を JSON.parse() に渡しました。文字列 "undefined" になり、先頭の u は妥当な JSON の開始文字ではありません。
「token o」や「token <」エラーと同じ?
同じファミリー、別の値。u = undefined;token o = オブジェクトが [object Object] に文字列化された;token < = HTML レスポンス。名前の文字が実際に渡されたものを教えてくれます。
なぜ JSON.parse(null) は同じエラーを投げない?
"null" は妥当な JSON なので JSON.parse(null) は null を返します。undefined(→ "undefined")だけが u エラーを引き起こします。
今すぐ直す
- JSON Fix —— ブラウザ内で JSON を検証・修復
- JSON.parse「Unexpected Token」エラーの直し方 —— 各 token のバリエーション
- Unexpected token o in JSON at position 1 —— オブジェクト系の双子エラー
- JavaScript で壊れた JSON を扱う方法 —— safe-parse パターン