Provided list of item keys contains duplicates(BatchWriteItem)

TL;DR — 你的 BatchWriteItem 請求中有兩個以上的操作作用在同一個主索引鍵上(同一個鍵被 put 兩次,或同時 put 與 delete)。單一批次不能對同一個項目動超過一次,所以 DynamoDB 會拒絕整個批次。送出之前,把重複項合併成每個鍵一個操作。

這是什麼意思

ValidationException: Provided list of item keys contains duplicates

BatchWriteItem 最多執行 25 個 put/delete 操作。請求中的每個操作都必須指向不同的主索引鍵。如果兩個 PutRequestDeleteRequest 項目解析到同一個鍵(分割區索引鍵,或分割區索引鍵+排序索引鍵),DynamoDB 會以這個 HTTP 400 ValidationException 讓整個呼叫失敗 — 什麼都不會寫入。原樣不可重試

為什麼會發生

  • 同一個項目在一個批次中被 put 兩次 — 常見於來源清單中有重複紀錄,而你把每一筆都對應成一個 PutRequest
  • 同一個鍵在同一批次中同時被 put 與 delete — 那仍然是對一個項目的兩個操作,一樣被拒絕。
  • 建立批次時沒有去重複 — 來自一串會重複同一個鍵的事件流。
  • 複合鍵的疏忽 — 兩筆你以為不同的資料列,其實共用相同的分割區索引鍵+排序索引鍵。
  • 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
  2. 如果你使用 Python 的 batch_writer,就用 boto3 的 overwrite_by_pkeysbatch_writer(overwrite_by_pkeys=['pk', 'sk']) 會在新加入的項目具有相同主索引鍵時丟棄先前緩衝的請求,因此每個鍵的最後一次寫入獲勝。
  3. 去重複之後,每次 BatchWriteItem 切成 25 個操作,並重試 UnprocessedItems(節流 — 那是另一回事)。
  4. 需要對同一個鍵先寫入再刪除? 把它們拆到不同的請求,或使用 TransactWriteItems(它同樣禁止對一個項目做兩個動作,但讓意圖更明確)。

要在執行前檢視一次大量載入?DynoTable 桌面應用程式會依鍵顯示項目,讓排在同一批次中的重複鍵一眼就看得出來。

重現方式

一個包含同一個主索引鍵兩次的 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 不會替你決定兩個重複項中哪一個該獲勝,所以請在建立請求之前先依鍵去重複。

相關錯誤

參考資料

最後於 2026-07-13 對照上方連結的官方 AWS 文件驗證。

已於 2026-07-26 對照 DynamoDB Local 2.x 與 AWS SDK for JavaScript v3.1095.0 重現 — 上方輸出為逐字原文。

不必透過主控台就能操作 DynamoDB

一款快速的 DynamoDB 桌面用戶端,可執行 DynamoDB 無法執行的真正 SQL — JOINs、GROUP BY、聚合 — 並支援視覺化編輯與使用你自己的 Bedrock 金鑰的 AI 代理。

30 天免費試用,無需信用卡 — 之後為無時間限制的免費方案。