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 duplicatesBatchWriteItem は最大25件の put/delete 操作を実行します。リクエスト内のすべての操作は、それぞれ異なるプライマリキーを対象にしなければなりません。2つの PutRequest/DeleteRequest エントリが同じキー(パーティションキー、またはパーティション + ソートキー)に解決される場合、DynamoDB はこの HTTP 400 の ValidationException で呼び出し全体を失敗させます — 何も書き込まれません。そのままでは リトライ不可 です。
発生する理由
- 同じアイテムを1つのバッチで2回 put している — ソースのリストに重複レコードがあり、それぞれを
PutRequestにマップしたときによく起きます。 - 同じバッチ内で同じキーの put と delete — それでも1つのアイテムに対する2操作であり、やはり拒否されます。
- キーが重複するイベントストリームから、重複排除せずにバッチを組み立てている。
- 複合キーの見落とし — 別物だと思っていた2行が、パーティション + ソートキーを共有している。
- キー単位でマージせずにチャンク分割する ETL / 一括ロードのジョブ(Glue、独自インポーター)。
修正方法
- キーごとに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 - Python の
batch_writerを使うなら boto3 のoverwrite_by_pkeysを使います —batch_writer(overwrite_by_pkeys=['pk', 'sk'])は、新たに追加されたアイテムが同じプライマリキーを持つときにバッファ済みのリクエストを破棄するので、キーごとに最後の書き込みが勝ちます。 - 重複排除の後、
BatchWriteItemあたり25操作にチャンク分割し、UnprocessedItemsを再試行します(スロットリング — これは別の問題です)。 - 同じキーを書いてから削除する必要がありますか? 別々のリクエストに分けるか、
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つの重複のどちらを勝たせるかを決めようとしません。だからリクエストを組み立てる前にキーで重複排除してください。
関連するエラー
- Provided list of item keys contains duplicates (BatchGetItem) — 読み取り側の同じルール。
- ConditionalCheckFailedException — 書き込み時に失敗したアイテム単位のガード。
- Code example: BatchWriteItem in Node.js — 応用できる正しいチャンク分割済みバッチ書き込み。
- 学習: バッチ操作
参考資料
- BatchWriteItem — Amazon DynamoDB API Reference
- Amazon DynamoDB — AWS SDK for Python (Boto3) guide (batch_writer / overwrite_by_pkeys)
- TransactWriteItems — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。
2026-07-26 に DynamoDB Local 2.x と AWS SDK for JavaScript v3.1095.0 で再現しました — 上記の出力はそのままの逐語です。