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

update expression 可以定址深層路徑(stats.daily.viewsitems[3].qty),但路徑的每一步(最後一步除外)都必須已經以相容型別存在於項目上。若項目沒有 stats 屬性 — 或 stats 是字串 — 就沒有地方可掛上 daily,該更新就會被拒絕。同樣的檢查也在交易內執行,它在那裡以 ValidationError 取消原因的形式浮現。

為什麼會發生

  • 父層 map 尚不存在 — 項目建立時沒有 stats,現在 SET stats.daily = :v 沒有 stats 可下探。
  • 父層以錯誤型別存在stats 是字串或數字,而非 map(M),因此沒有成員可定址。
  • 索引到一個不存在的 list — 當 items 不在項目上或不是 list 時使用 SET items[0].qty = :q
  • 路徑片段拼錯SET stat.daily = :v(少了 s)下探到一個不存在的屬性。
  • 不同項目有不同的形狀 — 更新在帶有該 map 的項目上有效,在沒有的項目上失敗(在混合實體的單一表格設計中很常見)。

如何修正

  1. 建立項目時初始化父層 map — 事先寫入 stats: {}(一個空的 M),巢狀更新就總是有地方落腳。

  2. 或按需建立父層,然後設定子層 — 兩次更新。 DynamoDB 不允許你在一個 expression 中同時做兩者(那是路徑重疊):

    // 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 風格的查詢,並在本機編輯項目。