The document path provided in the update expression is invalid for update
TL;DR — You're writing to a nested path (SET parent.child = :v) but parent doesn't exist on the item — or exists as a string/number instead of a map or list. DynamoDB does NOT auto-create intermediate maps. Create the parent first (SET #p = if_not_exists(#p, :emptyMap) in a prior update, or initialize {} when the item is created), then set the nested attribute.
What it means
ValidationException: The document path provided in the update expression
is invalid for updateAn update expression can address deep paths (stats.daily.views, items[3].qty), but every step of the path except the last must already exist on the item with a compatible type. If the item has no stats attribute — or stats is a string — there is nowhere to hang daily, and the update is rejected. The same check runs inside transactions, where it surfaces as a ValidationError cancellation reason.
Why it happens
- The parent map doesn't exist yet — the item was created without
stats, and nowSET stats.daily = :vhas nostatsto descend into. - The parent exists with the wrong type —
statsis a string or number, not a map (M), so it has no members to address. - Indexing into a missing list —
SET items[0].qty = :qwhenitemsisn't on the item or isn't a list. - A typo'd path segment —
SET stat.daily = :v(missings) descends into an attribute that isn't there. - Different items have different shapes — the update works on items that carry the map and fails on the ones that don't (common in single-table designs with mixed entities).
How to fix it
Initialize parent maps when you create the item — write
stats: {}(an emptyM) up front, and nested updates always have somewhere to land.Or create the parent on demand, then set the child — two updates. DynamoDB won't let you do both in one expression (that's a path overlap):
// 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'}Note
if_not_exists(stats.daily, :v)does not help here — it guards the value, not the missing parent.Replace the whole map instead when you own its full shape:
SET #s = :wholeMapworks whether or notstatsexisted.Verify the real item shape — read the item and check the parent attribute exists and is an
M/Lbefore assuming the path is valid.
The DynoTable desktop app shows every item's real nested structure at a glance — you can see whether stats is a map, a string, or missing entirely before you write to it.
Related errors
- Two document paths overlap with each other — why "create parent + set child" can't be one expression.
- The provided expression refers to an attribute that does not exist
- Invalid UpdateExpression: Syntax error
- Learn: Update expressions · Data types
References
- Using update expressions in DynamoDB — Amazon DynamoDB Developer Guide
- TransactWriteItems — Amazon DynamoDB API Reference
- Expression attribute names (aliases) in DynamoDB — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.