La lista de claves de Item indicada contiene duplicados (BatchWriteItem)

TL;DR — Tu solicitud BatchWriteItem contiene dos o más operaciones sobre la misma clave primaria (dos puts de una clave, o un put y un delete de ella). Un solo lote no puede actuar sobre un Item más de una vez, así que DynamoDB rechaza el lote entero. Colapsa los duplicados a una operación por clave antes de enviarlo.

Qué significa

ValidationException: Provided list of item keys contains duplicates

BatchWriteItem realiza hasta 25 operaciones de put/delete. Cada operación de la solicitud debe apuntar a una clave primaria distinta. Si dos entradas PutRequest/DeleteRequest resuelven a la misma clave (clave de partición, o partición + ordenación), DynamoDB falla toda la llamada con este ValidationException HTTP 400 — no se escribe nada. No se puede reintentar sin cambios.

Por qué ocurre

  • El mismo Item puesto dos veces en un lote — habitualmente cuando una lista de origen tiene registros duplicados y mapeas cada uno a un PutRequest.
  • Un put y un delete de la misma clave en el mismo lote — siguen siendo dos operaciones sobre un Item, sigue rechazándose.
  • Construir lotes sin deduplicar a lo largo de un flujo de eventos que repite una clave.
  • Descuido de clave compuesta — dos filas que creías distintas comparten clave de partición + ordenación.
  • Trabajos de ETL / carga masiva (Glue, importadores propios) que no fusionan por clave antes de trocear.

Cómo solucionarlo

  1. Colapsa a una operación por clave, manteniendo que gana la última escritura:
    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. Usa overwrite_by_pkeys de boto3 si usas el batch_writer de Python — batch_writer(overwrite_by_pkeys=['pk', 'sk']) descarta una solicitud en búfer cuando un Item recién añadido tiene la misma clave primaria, así que gana la última escritura de cada clave.
  3. Trocea a 25 operaciones por BatchWriteItem tras deduplicar, y reintenta UnprocessedItems (throttling — una cuestión aparte).
  4. ¿Necesitas escribir y luego borrar la misma clave? Sepáralos en solicitudes distintas, o usa TransactWriteItems (que también prohíbe dos acciones sobre un Item, pero hace la intención explícita).

¿Inspeccionando una carga masiva antes de ejecutarla? La aplicación de escritorio DynoTable muestra los Items por clave, así que las claves duplicadas en cola para el mismo lote saltan a la vista.

Reproducirlo

Un BatchWriteItem que contiene dos veces la misma clave primaria:

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

Salida real:

ValidationException: Provided list of item keys contains duplicates
HTTP 400

Se rechaza el lote entero — no aterriza ninguna de las dos escrituras. Como un lote no tiene garantía de orden, DynamoDB no va a decidir cuál de los dos duplicados debe ganar, así que deduplica por clave antes de construir la petición.

Errores relacionados

Referencias

Verificado por última vez el 2026-07-13 contra la documentación oficial de AWS enlazada arriba.

Reproducido el 2026-07-26 contra DynamoDB Local 2.x con AWS SDK for JavaScript v3.1095.0 — la salida de arriba es literal.

Trabaja con DynamoDB sin la Consola

Un cliente de escritorio rápido para DynamoDB que ejecuta el SQL real que DynamoDB no puede — JOINs, GROUP BY, agregaciones — con edición visual y un agente de IA con tus propias claves de Bedrock.

Prueba gratuita de 30 días, sin tarjeta — después, el plan Free sin límite de tiempo.