ExpressionAttributeNames contains invalid key: Syntax error
TL;DR — 问题出在你 ExpressionAttributeNames map 左侧的占位符键上,而不是它指向的属性。一个占位符必须是 # 后跟纯字母、数字或下划线(#name、#p0)。如果你把真实的属性名——连同它的点、连字符、+ 号或空格——放进占位符本身,DynamoDB 会拒绝这个 map。让占位符保持无趣;把杂乱的真实名称放在右侧。
含义
ValidationException: ExpressionAttributeNames contains invalid key:
Syntax error; key: "#my.attribute"ExpressionAttributeNames 把一个占位符标记(用在你的表达式内部)映射到一个真实的属性名。DynamoDB 在接触你的数据之前会验证占位符的语法:它必须以 # 开头,且只包含在表达式标记内部有效的字符。在表达式语法中有含义的特殊字符——.(路径分隔符)、-、+、空格——会使占位符本身无法解析,整个请求都会以这个 ValidationException 被拒绝。
为什么会发生
- 真实的属性名被复制进了占位符——例如
{"#stats.daily": "stats.daily"}。_键_中的点是一个语法错误,无论它映射到什么。 - 占位符中的特殊字符——连字符(
#user-id)、+号或空格。#之后只有字母数字和下划线是安全的。 - 缺少
#——ExpressionAttributeNames中的键必须以#开头;{"name": "name"}是无效的。 - 一个从属性名自动生成占位符的库,其属性名包含点或特殊字符,把该字符直接透传了过去。
如何修复
使用简单的占位符并把每个映射到真实名称:
{ ExpressionAttributeNames: {'#p0': 'user-id', '#p1': 'stats'}, KeyConditionExpression: '#p0 = :uid' }对于嵌套路径,分别为每个段起别名——每个路径元素一个占位符,在表达式中用字面的点连接:
// read stats.daily where the item has a top-level "stats" map { ProjectionExpression: '#s.#d', ExpressionAttributeNames: {'#s': 'stats', '#d': 'daily'} }注意反面情况:如果属性的_实际名称_包含一个字面的点(一个名为
"stats.daily"的属性,而非嵌套路径),那么为整个名称用一个占位符正是你想要的——{'#sd': 'stats.daily'}——这样点就被当作名称的一部分,而非路径分隔符。检查你的封装生成了什么——如果一个 ODM/辅助工具为你构建了这个 map,记录最终请求并检查它生成的占位符键。
在处理名称满是点和横线的属性?DynoTable 桌面应用会自动用正确起别名的名称构建查询,无论属性叫什么。
相关错误
- Attribute name is a reserved keyword——使用
ExpressionAttributeNames的另一个重要原因。 - Value provided in ExpressionAttributeNames unused in expressions
- Value provided in ExpressionAttributeValues unused
- 学习:Expression names & values
References
- Expression attribute names (aliases) in DynamoDB — Amazon DynamoDB Developer Guide
- Query — Amazon DynamoDB API Reference
- Reserved words in DynamoDB — Amazon DynamoDB Developer Guide
最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。