Two document paths overlap with each other
TL;DR — 一個 UpdateExpression 對每條 document path 只能觸及一次,且沒有路徑可以位於同一 expression 也觸及的另一條路徑_內部_。SET profile = :p, profile.email = :e 重疊了(profile.email 住在 profile 內部);將同一屬性指名兩次也是。將子層折入父層值,或拆成兩次更新。
這是什麼意思
ValidationException: Invalid UpdateExpression: Two document paths overlap
with each other; must remove or rewrite one of these paths;
path one: [profile], path two: [profile, email]DynamoDB 對照項目在更新前的屬性值求值 UpdateExpression 中的每個動作 — 動作不是從左到右一個接一個套用。若兩個動作鎖定重疊的路徑(同一屬性,或父層與其巢狀內部的東西),結果會有歧義:profile.email = :e 是在 profile = :p 替換整個 map 之前還是之後執行?DynamoDB 不猜測,而是直接拒絕該 expression。(相同的重疊檢查適用於 ProjectionExpression 中的重複路徑。)
為什麼會發生
- 在一個 expression 中設定父層與其子層 —
SET profile = :p, profile.email = :e。第二條路徑在第一條內部。 - 同一屬性出現兩次 —
SET updatedAt = :a REMOVE updatedAt,或SET tags = :t ADD tags :more。 - ODM/包裝器默默加上一條你也設定的路徑 — 經典情況:程式庫自動寫入時間戳或整個物件(
SET item = :obj),而你的程式碼也設定item.field(在 Dynamoose 帶自動createdAt/updatedAt時可見)。 - 一起更新 list 與其一個元素 —
SET mylist = :l, mylist[0] = :v。
如何修正
將子層折入父層值 — 若你反正要替換 map,把新的 email 放進去並捨棄第二個動作:
// instead of SET profile = :p, profile.email = :e UpdateExpression: 'SET #p = :p', ExpressionAttributeValues: {':p': {name: 'Ada', email: 'ada@example.com'}}或只更新葉節點 — 保持父層不動並個別設定巢狀欄位(
SET #p.#n = :n, #p.#e = :e)。同一父層下的兄弟路徑不重疊;只有巢狀才會。去重 — 確保每個屬性在
SET/REMOVE/ADD/DELETE中恰好出現於一個動作。檢查你程式庫的自動欄位 — 在你自己的 expression 已寫入它們的更新中,停用或排除自動管理的屬性(時間戳、版本)。
當你確實需要「替換父層,然後調整子層」語義時拆成兩個請求 — 兩個
UpdateItem呼叫,依序。
手動編輯巢狀 map 是重疊溜入之處 — DynoTable 桌面應用程式就地編輯項目的屬性,並為確切變更的內容發出乾淨、不重疊的更新。
相關錯誤
- The document path provided is invalid for update — 另一個巢狀路徑更新失敗(父層缺少而非被重複寫入)。
- Invalid UpdateExpression: Syntax error
- 學習:Update expressions
References
- Using update expressions in DynamoDB — Amazon DynamoDB Developer Guide
- Referring to item attributes when using expressions in DynamoDB — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。