The provided starting key is invalid
TL;DR — 你的 ExclusiveStartKey 与你正在分页的对象的键模式不匹配。它必须恰好包含 DynamoDB 在 LastEvaluatedKey 中返回的键属性——完整的主键,加上你查询 GSI/LSI 时的索引键——名称和类型都相同。把 LastEvaluatedKey 原样传回;手工拼装它正是这出错的地方。
含义
ValidationException: The provided starting key is invalidValidationException: Exclusive Start Key must have same size as table's key schemaExclusiveStartKey 告诉一个 Query/Scan 从哪里恢复。DynamoDB 会根据表的键模式——或者对于索引查询,LastEvaluatedKey 携带的组合索引键加表键——来验证它。缺少属性、多余属性、名称错误或类型错误都会在读取任何数据之前失败。
为什么会发生
- 只用分区键手工构建键——一个复合键表在起始键中需要分区_和_排序键。
- 只用表键对索引分页——GSI/LSI 查询上的
LastEvaluatedKey同时包含索引键属性和表的主键;它们全都必须传回。 - 类型或名称漂移——键被序列化了(JSON、URL 参数、缓存)并带着
"42"回来,而LastEvaluatedKey里是一个数字,或者带着一个改了名的字段。 - 跨查询复用键——把来自一张表/索引的
LastEvaluatedKey传给了针对另一个的查询,或者在键模式假设改变之后传给了同一个查询。 - 一个封装注入了默认值——一个 ODM 填入它以为属于键的属性,会把起始键撑过模式大小。
如何修复
原封不动地往返
LastEvaluatedKey:let ExclusiveStartKey; do { const page = await docClient.send( new QueryCommand({ TableName, KeyConditionExpression, ExpressionAttributeValues, ExclusiveStartKey }) ); items.push(...(page.Items ?? [])); ExclusiveStartKey = page.LastEvaluatedKey; // verbatim — no rebuild } while (ExclusiveStartKey);如果它跨越请求边界就无损地序列化它——当分页游标去往浏览器又回来时,编码整个
LastEvaluatedKey对象(例如其 JSON 的 base64),而不是从项目字段重建它,并保持数字类型仍为数字。为索引分页包含每个键属性——索引分区键/排序键_和_表分区键/排序键,与返回的完全一致。
不要捏造一个起始点——DynamoDB 分页没有偏移量;如果你需要"从 X 附近开始",就在
KeyConditionExpression(sk > :x)中表达它,而不是手工制作一个ExclusiveStartKey。
检查你的表或索引的 LastEvaluatedKey 实际包含什么,能免去猜测——DynoTable 桌面应用会翻页浏览查询并显示原始游标,而 DynamoDB Expression Builder 会围绕它组合查询请求。
相关错误
- The provided key element does not match the schema——
GetItem/写入键上的同一个模式不匹配。 - Query key condition not supported
- 代码示例:Get all items in Node.js · in Python (boto3)——做对了的 LastEvaluatedKey 分页循环。
- 学习:Pagination in DynamoDB
References
- Paginating table query results in DynamoDB — Amazon DynamoDB Developer Guide
- Query — Amazon DynamoDB API Reference
- Scan — Amazon DynamoDB API Reference
最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。