The document path provided in the update expression is invalid for update

TL;DR — 你在向一个嵌套路径(SET parent.child = :v)写入,但项目上的 parent 不存在——或者以字符串/数字而非 map 或 list 的形式存在。DynamoDB 不会自动创建中间的 map。先创建父级(在前一次更新中用 SET #p = if_not_exists(#p, :emptyMap),或在创建项目时初始化 {}),然后再设置嵌套属性。

含义

ValidationException: The document path provided in the update expression
is invalid for update

一个更新表达式可以定位深层路径(stats.daily.viewsitems[3].qty),但路径的每一步——除了最后一步——都必须已经以兼容的类型存在于项目上。如果项目没有 stats 属性——或者 stats 是一个字符串——那就无处可挂 daily,更新会被拒绝。同样的检查也在事务内部运行,在那里它以 ValidationError 取消原因的形式浮现。

为什么会发生

  • 父级 map 尚不存在——项目在创建时没有 stats,现在 SET stats.daily = :v 没有 stats 可供深入。
  • 父级以错误的类型存在——stats 是一个字符串或数字,而不是 map(M),因此它没有可定位的成员。
  • 索引进一个不存在的 list——SET items[0].qty = :q,而 items 不在项目上或不是一个 list。
  • 路径段拼写错误——SET stat.daily = :v(缺了 s)深入到一个不存在的属性中。
  • 不同项目有不同的形态——更新在带该 map 的项目上生效,而在不带的项目上失败(在混合实体的单表设计中很常见)。

如何修复

  1. 在创建项目时初始化父级 map——预先写入 stats: {}(一个空的 M),嵌套更新就总有落脚之处。

  2. 或者按需创建父级,然后设置子级——两次更新。 DynamoDB 不允许你在一个表达式里同时做这两件事(那会是路径重叠):

    // update 1 — create the map only if it's missing
    UpdateExpression: 'SET #s = if_not_exists(#s, :empty)',
    ExpressionAttributeNames: {'#s': 'stats'},
    ExpressionAttributeValues: {':empty': {}}
    
    // update 2 — now the nested set is safe
    UpdateExpression: 'SET #s.#d = :v',
    ExpressionAttributeNames: {'#s': 'stats', '#d': 'daily'}

    注意 if_not_exists(stats.daily, :v) 在这里没有帮助——它守护的是_值_,而不是缺失的父级。

  3. 改为替换整个 map,当你掌握它的完整形态时:SET #s = :wholeMap 无论 stats 是否存在都有效。

  4. 核实真实的项目形态——在假定路径有效之前,读取项目并检查父级属性存在且是一个 M/L

DynoTable 桌面应用让你一眼看到每个项目的真实嵌套结构——在你写入之前,你就能看出 stats 是一个 map、一个字符串,还是完全缺失。

相关错误

References

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

无需控制台即可使用 DynamoDB

DynoTable 是面向 DynamoDB 的快速桌面客户端 —— 浏览表、运行 SQL 风格的查询,并在本地编辑项。