YAMLの重複キーの検出と修正

YAMLの重複キーがどのようにサイレントなデータ損失を引き起こすかを学びます。異なるパーサーが重複をどのように処理するか、バリデーターで検出する方法、この一般的な落とし穴を避けるためのベストプラクティスを理解します。

Validation

詳細な説明

YAMLの重複キー

YAMLマッピングの重複キーは最も危険なYAMLの落とし穴の一つです。YAML 1.1仕様では技術的に有効ですが、サイレントなデータ損失を引き起こします — 最後の出現が前のものを静かに上書きします。

問題

database:
  host: primary.db.example.com
  port: 5432
  host: replica.db.example.com    # 最初の'host'を静かに上書き

パース後、host の値は replica.db.example.com になり、ほとんどのパーサーからエラーや警告は出ません。

重複が発生する理由

  1. 大きなファイル — 数百行のファイルでは、同じマッピング内にキーが既に存在することに気づかずにキーを追加しやすい
  2. マージコンフリクト — Gitマージは両方のブランチが同じYAMLセクションを変更すると重複キーを生成する可能性がある
  3. コピペエラー — ブロックを複製してキー名の更新を忘れる
  4. チームコラボレーション — 複数の人が調整なしに同じセクションにキーを追加する

YAMLスペックバージョン

  • YAML 1.1 — 重複キーは警告を生成するが有効。最後の値が勝つ
  • YAML 1.2 — 重複キーはエラー。重複のあるドキュメントは無効

ほとんどのパーサー(PyYAML、js-yaml、SnakeYAMLを含む)はYAML 1.1の動作に従い、重複を静かに受け入れます。

検出方法

  1. 厳密モードパーサー — 一部のパーサーは重複を拒否する厳密モードを提供
  2. リンターyamllint のようなツールには forbid-duplicated-keys ルールがある
  3. オンラインバリデーター — YAMLバリデーターは行番号付きで重複キーをフラグ付け
  4. IDEプラグイン — VS Code YAML拡張機能はリアルタイムで重複キーをハイライト

予防策

  • 重複キーを拒否するYAMLリンターをCIパイプラインに使用する
  • エディタを重複について警告するように設定する
  • 大きな設定ファイルの場合、複数の小さなファイルに分割することを検討する
  • ブロック全体を複製する代わりにアンカーとエイリアスを使用する
  • マージコンフリクト解決時にYAMLのdiffを慎重にレビューする

ネストされた重複

重複キーは同じマッピングレベル内でのみ問題です。異なるネストレベルでの同じキー名は完全に有効です:

# これは問題なし — 異なるマッピングレベル
production:
  host: prod.example.com
staging:
  host: staging.example.com

ユースケース

重複キー検出は大規模な設定ファイルを管理するチームにとって不可欠です。500行のKubernetesマニフェストやAnsibleインベントリでは、不正なマージからの重複キーがアプリケーションの動作を静かに変更する可能性があります。CIに重複キーチェックを統合することで、パーサーが静かに受け入れる設定エラーによる本番インシデントを防止できます。

試してみる — YAML Formatter & Validator

フルツールを開く