Provided list of item keys contains duplicates (BatchGetItem)

TL;DR — 你的 BatchGetItem 中某张表的 Keys 数组多次列出了同一个主键。DynamoDB 要求批次中的每个键都唯一,并会拒绝整个请求——它不会悄悄丢弃重复项。在发送前对键列表去重。

含义

ValidationException: Provided list of item keys contains duplicates

BatchGetItem 跨表读取最多 100 个项目。在单张表的 Keys 列表内,每个条目必须是一个不同的主键(分区键,或复合表的分区键 + 排序键)。两个解析到同一个键的条目会触发这个 HTTP 400 ValidationException,整个调用失败——不返回任何项目。它原样不可重试

为什么会发生

  • 同一个键出现两次——常常是因为 ID 从多个来源收集而来且从未合并。
  • 一个生成的键列表(例如把一个记录列表映射为键),其源有重复行。
  • 复合键混淆——两个条目共享分区键,但你忘了排序键有所不同;或者两者确实完全相同。
  • 大小写/类型差异掩盖了真实的重复——两个键 marshal 成同一个值。
  • 加载流水线(Glue、自定义 ETL)在没有去重步骤的情况下批量处理键。

如何修复

  1. 在调用前去重。 用一个稳定的字符串为每个条目做键,只保留一个:
    const seen = new Set();
    const keys = raw.filter((k) => {
      const id = `${k.pk.S}#${k.sk?.S ?? ''}`;
      if (seen.has(id)) return false;
      seen.add(id);
      return true;
    });
  2. 记住批次是一个集合,而非多重集——每个键你只需要读一次;无论如何项目都只返回一次。
  3. 每个 BatchGetItem 分块到 100 个键,并处理响应中的 UnprocessedKeys(限流,而非重复)。
  4. 用同样的去重来守护你的 ETL/加载器,这样问题就不会在上游复发。

在手工读取批次时想看清你到底在发送哪些键?DynoTable 桌面应用按键列出项目,因此一个工作集中意外的重复项很容易被发现。

DynoTable 中的路径

在批量读取生产中的键之前,请在 DynoTable 中发现重复项 — 使用 ⌘K 打开表,筛选出你计划获取的 ID,并确认每个主键出现一次。项目列表并排显示分区键和排序键,因此复合键冲突很明显。当你将读取移至代码中时,首先使用 Query Builder 构建单键读取原型,然后扩展到分块 BatchGetItem。使用 ⌘P 切换配置文件;在“设置”→“配置文件”下使用“Test Connection”配置它们。参见连接 AWS安装

来源

相关错误

参考资料

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。