← 記事一覧

JSON 内の未終端文字列: 原因と修正

JSON 内の未終端文字列は開きクオートに対応する閉じクオートがないこと —— 普通はエスケープ忘れのクオート、生の改行、または切り詰められたデータ。壊れた例と修正例で解説。

SyntaxError: Unterminated string in JSON at position N は、パーサが文字列を読み始め(開きの " を見て)、閉じの " を見つける前に入力の終わり —— あるいは改行 —— に達した、という意味です。文字列が閉じられませんでした。原因と直し方を説明します。

どの文字列エラーですか?

  • Unterminated string —— " で開かれた文字列が閉じられていない。
  • Bad control character —— 生の tab/改行/null バイトが文字列のにエスケープなしで含まれる。
  • Bad escaped character —— \ の後に JSON が許さないものが続く(例:\x、Windows パス)。

エラーの見え方

// V8 (Chrome / Node / Edge)
SyntaxError: Unterminated string in JSON at position 27

// Firefox
SyntaxError: JSON.parse: unterminated string at line 2 column 10 of the JSON data

// Safari
SyntaxError: JSON Parse error: Unterminated string

位置は、閉じなかった文字列の開きの引用符(またはその直後)を指します —— そこから先を見ましょう。

なぜ起きるか

原因 1 —— エスケープされていない引用符が文字列を早く閉じる

値の中の素の " は文字列を早期に閉じます;行の残りは予期しないトークンとして読まれ、本当の文字列は「開きっぱなし」になります。

// ❌ 壊れ —— hello の前の引用符が "He said " を閉じる
{ "note": "He said "hello" to her" }

// ✅ 修正 —— 内側の引用符をバックスラッシュでエスケープ
{ "note": "He said \"hello\" to her" }

原因 2 —— 文字列内に生の改行

JSON 文字列は生の改行を跨げません。リテラルの改行は文字列を切り、閉じられない状態にします。

// ❌ 壊れ —— 文字列内に実際の改行
{ "bio": "line one
line two" }

// ✅ 修正 —— \n エスケープを使い、生の改行なし
{ "bio": "line one\nline two" }

原因 3 —— データの切り詰め

文字列の途中で切れたレスポンス(コネクション切断、バッファ/サイズ上限、部分読み)は入力の末尾で文字列を開きっぱなしにします。

// 届いた内容(コネクションが切れた):
{"user":{"name":"Ada Lovel
// → Unterminated string

修正の手順

  1. 報告された位置へ、対応する閉じがない開きの " を見つける。
  2. 値内の未エスケープの " を探す —— \" にエスケープ。
  3. 値内の生の改行/tab を探す —— \n / \t に置き換える。
  4. 切り詰めをチェック —— バイト長を Content-Length と比較;短ければデータが切られています(テキスト修正ではなくコード修正)。
  5. JSON を手組みするのをやめる。 JSON.stringify() を使えば引用符と制御文字を自動エスケープしてくれます。
// 予防:文字列連結で JSON を作らない
const json = JSON.stringify({ note: userInput }); // 常に有効

よくある質問

「Unterminated string in JSON」の原因は?

開きの " に対応する閉じの " がない —— 多くは値内の未エスケープの引用符、生の改行、または文字列途中で切られたレスポンス。

JSON 文字列に引用符や改行をどう含めますか?

エスケープします:ダブルクォートは \"、改行は \n、タブは \tJSON.stringify() で JSON を作れば自動で行われます。

「Unexpected end of JSON input」と同じ?

関連しますが別物。「Unterminated string」は文字列が開きっぱなし;「Unexpected end of JSON input」 は構造(オブジェクト/配列)全体が早く終わった、という意味。切り詰められたレスポンスはどちらも引き起こせます。

今すぐ直す