壊れたJSONの修復:よくあるエラーと自動修正
JSONは仕様上、厳格です。JavaScriptと異なり、クォートの欠落、末尾のカンマ、コメントに対して一切の寛容さがありません。JSONが壊れると、パーサーは不可解なエラーをスローしてアプリケーションは動作を停止します。このガイドでは、JSONが壊れる理由、最も一般的なエラーパターン、そして手動または自動で修復する方法を解説します。
JSONが壊れる理由
JSONの破損は、本番環境で生成されたデータではほとんど発生しません。ほぼ常に人間の操作から生じます。
手動編集
開発者はJSONの設定ファイル、モックデータ、APIペイロードを頻繁に手動編集します。クォートを1つ見落としたり、余分なカンマを追加したりするだけでドキュメント全体が無効になります。JSONに対応したリンティングのないテキストエディターはセーフティネットを提供しません。
不完全なコピー&ペースト
ブラウザコンソール、ログファイル、チャットメッセージからJSONスニペットをコピーすると、構造の一部しかキャプチャできないことがよくあります。閉じられていない括弧、欠けているキー、孤立した値が残ります。
切り詰められたログ
ログ集約システムには行数またはバイト数の制限があります。制限を超えるJSONオブジェクトは途中で切り詰められ、パースできない構造的に無効なフラグメントが残ります。パースする前に再構築する必要があります。
フォーマットの混同
開発者がJavaScriptの構文(シングルクォート、クォートなしのキー、コメント)を使ってJSONを書き、厳格なJSONパーサーでパースしようとすることがあります。結果は常にパースエラーです。
よくあるエラーパターン
末尾のカンマ
最も頻繁なJSONのミスです。JSONはオブジェクトや配列の最後の要素の後にカンマを許可しません。
// 無効{"name": "Alice","age": 30,}// 有効{"name": "Alice","age": 30}
配列も同じルールです。
// 無効["red", "green", "blue",]// 有効["red", "green", "blue"]
シングルクォート
JSON文字列はダブルクォートが必要です。シングルクォートはJavaScriptの慣習であり、JSONの標準ではありません。
// 無効{ 'host': 'localhost', 'port': 5432 }// 有効{ "host": "localhost", "port": 5432 }
コメント
JSONにはコメント構文がありません。//も/* */も仕様に含まれていません。
// 無効{// データベース接続"host": "localhost","port": 5432 /* デフォルトポート */}// 有効{"host": "localhost","port": 5432}
設定ファイルにコメントが必要な場合は、JSONC(コメント付きJSON)またはYAMLを検討し、パーサーに渡す前にプレーンJSONに変換してください。
クォートなしのキー
オブジェクトのキーは必ずクォートされた文字列でなければなりません。裸の識別子は許可されていません。
// 無効{ host: "localhost", port: 5432 }// 有効{ "host": "localhost", "port": 5432 }
欠落または余分な括弧
不完全なコピー&ペーストにより、閉じられていない開き括弧や波括弧が残ることがよくあります。
// 無効 — 配列が閉じられていない[{ "id": 1, "name": "Alice" },{ "id": 2, "name": "Bob"// 有効[{ "id": 1, "name": "Alice" },{ "id": 2, "name": "Bob" }]
エスケープされていない文字
文字列内の特殊文字は適切にエスケープする必要があります。エスケープされていない制御文字、生の改行、無効なUnicodeシーケンスはパースの失敗を引き起こします。
// 無効 — 文字列内の生のタブ文字{ "query": "SELECT * FROM users" }// 有効 — エスケープされたタブ{ "query": "SELECT *\tFROM users" }
手動修復の戦略
小さなJSONドキュメントなら、手動修復は簡単です。
- エラーメッセージを注意深く読む。 ほとんどのパーサーは行番号と列番号を報告します。その位置に直接移動します。
- 括弧のバランスを確認する。 開き
{と[を閉じ}と]に対してカウントします。一致しなければなりません。 - 末尾のカンマをスキャンする。 すべての
}と]の前にある最後の要素を確認します。 - シングルクォートを置換する。
'を"にグローバルに置換すればほとんどのクォートの問題が解決しますが、文字列値内のアポストロフィを置換しないよう注意します。 - コメントを削除する。 パース前にすべての
//と/* */の行を削除します。
大きなドキュメントでは、手動修復はエラーが発生しやすく時間もかかります。
自動修復
自動修復ツールはヒューリスティックなルールを適用して、壊れた入力から有効なJSONを再構築します。最も一般的なパターンを確実に処理します。
| エラーの種類 | 自動修復のアプローチ | 信頼性 |
|---|---|---|
| 末尾のカンマ | }または]の前のカンマを削除 | 高い |
| シングルクォート | ダブルクォートに置換 | 高い |
| クォートなしのキー | 裸の識別子をダブルクォートで囲む | 高い |
| コメント | //と/* */ブロックを削除 | 高い |
| 閉じ括弧の欠落 | 推測される閉じトークンを追加 | 中程度 |
| 切り詰められた値 | 開いている文字列を閉じ、欠けている値を推測 | 低い |
自動修復が機能するケース
自動修復は、ドキュメントの構造がほぼ保たれていて構文上の問題のみを修正する必要がある場合に信頼性があります。理想的なケースです。
- 末尾のカンマを残して保存してしまった設定ファイル
- JavaScriptコンソールから貼り付けたログスニペット(出力にシングルクォートを使用)
- キーをクォートするのを忘れた開発者が書いたJSONオブジェクト
- 有効なJSONにする必要がある開発者コメント付きのドキュメント
これらのシナリオでは、修復ツールはデータを損失することなく完全に有効なJSONを再構築できます。
自動修復が失敗するケース
修復ツールはセマンティックな意図を回復できません。以下の場合は失敗するか不正な出力を生成します。
- 深刻な切り詰め。 ドキュメントの半分が欠けている場合、ツールは開いている括弧を閉じることができますが、結果のJSONは不完全で作者が意図したものを表さない可能性があります。
- 曖昧な構造。 周囲のコンテキストがない裸の値
helloは、キー、文字列値、識別子のいずれかを確実に分類できません。 - エンコードの破損。 JSONストリームに注入されたバイナリデータや文字セットエンコードの不一致は、全く異なる種類の修正が必要です。
- ネストされたクォートの競合。 エスケープされていないダブルクォートを含む文字列値は、ヒューリスティックな修復が安全に解決できない曖昧さを生み出します。
自動修復された出力は、本番環境で使用する前に必ず検査してください。
JSONKitの修復ツールの使い方
JSONKitのRepairツールは壊れたJSON入力に対して多層的な修復パイプラインを適用します。
- 壊れたJSONを貼り付けるかアップロードする
- ツールがエラーパターンを識別して適切な修正を適用する
- diffビューで修復された出力を確認して正確に何が変わったかを見る
- 修正されたJSONをコピーするかファイルとしてダウンロードする
diffビューは特に便利です。修復が構文のみを変更し、データの値を変えていないことを確認できます。
まとめ
JSONエラーは人間が関わる限り避けられません。よくある失敗パターン(末尾のカンマ、シングルクォート、クォートなしのキー、コメント、切り詰め)を理解することで、問題を素早く診断するための明確なメンタルモデルが身につきます。単純な構文上の問題なら、自動修復ツールが数秒で修正します。深刻に破損したデータでは、基礎となる構造を理解することが回復への唯一の確実な道です。