"Unexpected end of JSON input" の直し方
JSON.parse や res.json() でSyntaxError: Unexpected end of JSON input が出るのは、JSONとして完結する前に入力が終わったときです。実際の原因はほぼ 「空文字列」「空レスポンス」「途中で切れたJSON」の3つに絞れます。
This guide explains why JSON.parsethrows "Unexpected end of JSON input" and walks through the three real-world causes: empty strings, empty response bodies, and truncated JSON.
TL;DR
- 最頻出は
JSON.parse("")。localStorage の未保存キーや空のAPIボディが典型 - fetch なら 204 No Content・エラー時の空ボディを疑う。
res.json()の前にステータス確認 - ログや文字列連結で JSONが途中で切れていないかはJSON整形ツールに貼ると一瞬で分かる
JSONエラーを診断
JSON文字列またはエラーメッセージから、よくある原因と修正方法を推測します。
1. エラーの意味 / What the error means
パーサーは { や [ を読み始めると、対応する閉じ記号まで読み切ろうとします。 その途中で入力が尽きると「end of input(入力の終端)に予期せず到達した」としてこのエラーになります。 つまり壊れた文字があるのではなく、続きが無いのが特徴です (壊れた文字がある場合は Unexpected token エラーになります)。
The parser reached the end of the string while a JSON value was still open. Nothing is malformed — the rest of the document is simply missing.
2. 原因別の対処 / Causes and fixes
| 状況 / Situation | 原因 / Cause | 対処 / Fix |
|---|---|---|
JSON.parse(localStorage.getItem(...)) | 値が ""(空文字列) / Empty string | v ? JSON.parse(v) : null でガード |
res.json() が reject する | 204/205 や DELETE 成功時の空ボディ / Empty body | ステータスで分岐してから parse |
| エラー時だけ落ちる | サーバーが 500 で空ボディを返す / Empty error body | res.ok を先に確認 |
| ログから拾ったJSONで発生 | 出力が文字数制限で切れた / Truncated log | 元データを再取得(ログは信用しない) |
| 大きなファイルの読み込みで発生 | 書き込み未完了・転送中断 / Incomplete write | 生成側で flush/close を確認 |
| ストリーミング受信で発生 | チャンク単位で逐次 parse している / Parsing partial chunks | 全チャンク連結後に parse(または NDJSON 化) |
3. fetch の安全な書き方 / Safe fetch pattern
const res = await fetch(url);
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
// 204 や空ボディでも落ちない
const text = await res.text();
const data = text ? JSON.parse(text) : null;res.json() を直接呼ばず一度 text() で受けてから判定するのが 最も堅牢です。ステータスコードの意味はHTTPステータスコード検索で確認できます。
4. ブラウザ・環境ごとの文言差 / Error wording by environment
- Chrome / Node.js:
Unexpected end of JSON input - Firefox:
JSON.parse: unexpected end of data at line 1 column 1 - Safari:
JSON Parse error: Unexpected EOF
文言は違っても原因と対処は同じです。検索するときはこのページの3原因(空文字列・空ボディ・途中切れ)を順に当てはめてください。
このサイトの自動診断ツールでの見分け方 / How our error diagnoser tells these apart
この記事の上部にも埋め込まれている JsonErrorDiagnoser は、入力されたエラーメッセージ文字列から unexpected end や end of data などのキーワードを正規表現で検出します。その場合は「Unexpected token」系とは分けて、空レスポンス、HTTPステータスの確認漏れ、JSONの途中切れを原因候補として提示する設計です。
単なるキーワード一致だけでなく、エラーメッセージ内の position N や line N column N という表記から位置情報も抽出し、入力のどこで問題が起きたかを示そうとします。
The embedded JsonErrorDiagnoser uses regular expressions to recognize messages such as unexpected end and end of data, then suggests empty responses, unchecked HTTP status codes, or truncated JSON rather than the usual “Unexpected token” causes. It also attempts to extract location details from position N and line N column N forms.
5. English summary
JSON.parsethrows "Unexpected end of JSON input" when the input ends while a JSON value is still open. In practice the cause is almost always one of three things: parsing an empty string (e.g. a missing localStorage key), calling response.json() on an empty body (204 No Content, DELETE responses, or error responses with no payload), or JSON that was truncated by a log line limit or an incomplete file write. Guard withconst text = await res.text(); const data = text ? JSON.parse(text) : null; and checkres.okbefore parsing. Firefox reports the same problem as "unexpected end of data" and Safari as "Unexpected EOF".
よくある質問 / FAQ
- JSON.parse("") はなぜこのエラーになる?
- 空文字列は「JSONの値が始まる前に入力が終わった」状態のため、Unexpected end of JSON input になります。値が無い可能性があるなら text ? JSON.parse(text) : null のようにガードします。
- 204 No Content のレスポンスで res.json() を呼ぶとどうなる?
- ボディが空のため Unexpected end of JSON input で reject されます。ステータスが 204 や 205 の場合は res.json() を呼ばない分岐を入れます。
- Why does an empty fetch response throw this error?
- response.json() internally runs JSON.parse on the body text. An empty body means the parser reaches the end of input before finding a JSON value, so it throws. Read response.text() first and parse only when it is non-empty.
関連ツール / Related tools
- JSON Formatter & Validator - 貼り付けるだけで切れている位置を特定
- HTTP Status Code 検索
- JSON Schema Validator