Provided list of item keys contains duplicates (BatchWriteItem)

TL;DR — Sua requisição BatchWriteItem contém duas ou mais operações na mesma chave primária (dois puts de uma chave, ou um put e um delete dela). Um único lote não pode agir em um item mais de uma vez, então o DynamoDB rejeita o lote inteiro. Colapse as duplicatas para uma operação por chave antes de enviar.

O que significa

ValidationException: Provided list of item keys contains duplicates

BatchWriteItem executa até 25 operações de put/delete. Cada operação na requisição precisa mirar uma chave primária distinta. Se duas entradas PutRequest/DeleteRequest resolvem para a mesma chave (chave de partição, ou partição + ordenação), o DynamoDB falha a chamada inteira com este HTTP 400 ValidationException — nada é escrito. Não é retentável inalterado.

Por que isso acontece

  • O mesmo item colocado duas vezes em um lote — comumente quando uma lista de origem tem registros duplicados e você mapeia cada um para um PutRequest.
  • Um put e um delete da mesma chave no mesmo lote — ainda são duas operações em um item, ainda rejeitado.
  • Construir lotes sem de-duplicar ao longo de um fluxo de eventos que repetem uma chave.
  • Descuido com chave composta — duas linhas que você achava distintas compartilham chave de partição + ordenação.
  • Jobs de ETL / bulk-load (Glue, importadores customizados) que não mesclam por chave antes de dividir em blocos.

Como corrigir

  1. Colapse para uma operação por chave, mantendo o comportamento de última escrita vence:
    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. Use o overwrite_by_pkeys do boto3 se você usa o batch_writer do Python — batch_writer(overwrite_by_pkeys=['pk', 'sk']) descarta uma requisição em buffer quando um item recém-adicionado tem a mesma chave primária, então a última escrita de cada chave vence.
  3. Divida em 25 operações por BatchWriteItem após de-duplicar, e tente novamente UnprocessedItems (throttling — uma preocupação separada).
  4. Precisa escrever e depois excluir a mesma chave? Divida-os em requisições separadas, ou use TransactWriteItems (que também proíbe duas ações em um item, mas torna a intenção explícita).

Inspecionando um bulk load antes de rodá-lo? O app desktop DynoTable mostra os itens por chave para que chaves duplicadas enfileiradas para o mesmo lote se destaquem.

Reproduza

Um BatchWriteItem contendo a mesma chave primária duas vezes:

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

Saída real:

ValidationException: Provided list of item keys contains duplicates
HTTP 400

O lote inteiro é rejeitado — nenhuma das duas escritas passa. Como um lote não tem garantia de ordenação, o DynamoDB não vai decidir qual das duas duplicatas deve vencer, então de-duplique por chave antes de montar a requisição.

Erros relacionados

Referências

Verificado pela última vez em 2026-07-13 contra a documentação oficial da AWS vinculada acima.

Reproduzido em 2026-07-26 no DynamoDB Local 2.x com o AWS SDK for JavaScript v3.1095.0 — a saída acima é literal.

Trabalhe com o DynamoDB sem o Console

Um cliente desktop rápido para DynamoDB que roda o SQL de verdade que o DynamoDB não consegue — JOINs, GROUP BY, agregações — com edição visual e um agente de IA com suas próprias chaves do Bedrock.

Teste grátis de 30 dias, sem cartão de crédito — depois o plano Grátis sem limite de tempo.