Provided list of item keys contains duplicates (BatchWriteItem)

TL;DR — BatchWriteItem リクエストに、同じプライマリキーに対する操作が2つ以上含まれています(同じキーの put が2回、あるいは put と delete)。1つのバッチが1つのアイテムに対して2回以上作用することはできないため、DynamoDB はバッチ全体を拒否します。送信前に、キーごとに1操作へ重複をまとめてください。

意味

ValidationException: Provided list of item keys contains duplicates

BatchWriteItem は最大25件の put/delete 操作を実行します。リクエスト内のすべての操作は、それぞれ異なるプライマリキーを対象にしなければなりません。2つの PutRequest/DeleteRequest エントリが同じキー(パーティションキー、またはパーティション + ソートキー)に解決される場合、DynamoDB はこの HTTP 400 の ValidationException で呼び出し全体を失敗させます — 何も書き込まれません。そのままでは リトライ不可 です。

発生する理由

  • 同じアイテムを1つのバッチで2回 put している — ソースのリストに重複レコードがあり、それぞれを PutRequest にマップしたときによく起きます。
  • 同じバッチ内で同じキーの put と delete — それでも1つのアイテムに対する2操作であり、やはり拒否されます。
  • キーが重複するイベントストリームから、重複排除せずにバッチを組み立てている。
  • 複合キーの見落とし — 別物だと思っていた2行が、パーティション + ソートキーを共有している。
  • キー単位でマージせずにチャンク分割する ETL / 一括ロードのジョブ(Glue、独自インポーター)。

修正方法

  1. キーごとに1操作へまとめます。 最後の書き込みを勝たせます:
    import {marshall} from '@aws-sdk/util-dynamodb';
    
    const byKey = new Map();
    for (const item of records) {
      byKey.set(`${item.pk}#${item.sk ?? ''}`, {PutRequest: {Item: marshall(item)}});
    }
    const batch = [...byKey.values()]; // <= one op per key
  2. Python の batch_writer を使うなら boto3 の overwrite_by_pkeys を使いますbatch_writer(overwrite_by_pkeys=['pk', 'sk']) は、新たに追加されたアイテムが同じプライマリキーを持つときにバッファ済みのリクエストを破棄するので、キーごとに最後の書き込みが勝ちます。
  3. 重複排除の後、BatchWriteItem あたり25操作にチャンク分割しUnprocessedItems を再試行します(スロットリング — これは別の問題です)。
  4. 同じキーを書いてから削除する必要がありますか? 別々のリクエストに分けるか、TransactWriteItems を使います(こちらも1アイテムに対する2アクションを禁じますが、意図が明示的になります)。

一括ロードを実行する前に中身を確認したいですか? DynoTable デスクトップアプリはアイテムをキー別に表示するので、同じバッチに並んだ重複キーが目立ちます。

再現方法

同じプライマリキーを2回含む BatchWriteItem です。

await client.send(
  new BatchWriteItemCommand({
    RequestItems: {
      orders: [
        {PutRequest: {Item: {pk: {S: 'DUP'}, sk: {S: 'META'}}}},
        {PutRequest: {Item: {pk: {S: 'DUP'}, sk: {S: 'META'}}}}
      ]
    }
  })
);

実際の出力:

ValidationException: Provided list of item keys contains duplicates
HTTP 400

バッチ全体が拒否されます — どちらの書き込みも着地しません。バッチには順序の保証がないため、DynamoDB は2つの重複のどちらを勝たせるかを決めようとしません。だからリクエストを組み立てる前にキーで重複排除してください。

関連するエラー

参考資料

最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。

2026-07-26 に DynamoDB Local 2.x と AWS SDK for JavaScript v3.1095.0 で再現しました — 上記の出力はそのままの逐語です。

Console なしで DynamoDB を扱う

DynamoDB では実行できない本物の SQL(JOINs、GROUP BY、集計)を実行する高速な DynamoDB デスクトップクライアント。ビジュアル編集と、あなた自身の Bedrock キーで動く AI エージェントを備えています。

30日間無料トライアル、クレジットカード不要 — その後は期限のない Free プラン。