Two document paths overlap with each other

TL;DR — One UpdateExpression may touch each document path only once, and no path may sit inside another path the same expression also touches. SET profile = :p, profile.email = :e overlaps (profile.email lives inside profile); so does naming the same attribute twice. Fold the child into the parent value, or split into two updates.

What it means

ValidationException: 1 validation error detected: 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 evaluates every action in an UpdateExpression against the item's attribute values as they were before the update — actions aren't applied one after another from left to right. If two actions target overlapping paths (the same attribute, or a parent and something nested inside it), the result would be ambiguous: does profile.email = :e run before or after profile = :p replaces the whole map? Rather than guess, DynamoDB rejects the expression outright. (The same overlap check applies to duplicate paths in a ProjectionExpression.)

Why it happens

  • Setting a parent and its child in one expressionSET profile = :p, profile.email = :e. The second path is inside the first.
  • The same attribute appears twiceSET updatedAt = :a REMOVE updatedAt, or SET tags = :t ADD tags :more.
  • An ODM/wrapper silently adds a path you also set — the classic case: a library auto-writes a timestamp or the whole object (SET item = :obj) while your code also sets item.field (seen in Dynamoose with auto createdAt/updatedAt).
  • Updating a list and one of its elements togetherSET mylist = :l, mylist[0] = :v.

How to fix it

  1. Fold the child into the parent value — if you're replacing the map anyway, put the new email inside it and drop the second action:

    // instead of SET profile = :p, profile.email = :e
    UpdateExpression: 'SET #p = :p',
    ExpressionAttributeValues: {':p': {name: 'Ada', email: 'ada@example.com'}}
  2. Or update only the leaves — keep the parent untouched and set the nested fields individually (SET #p.#n = :n, #p.#e = :e). Sibling paths under the same parent don't overlap; only nesting does.

  3. Deduplicate — make sure each attribute appears in exactly one action across SET/REMOVE/ADD/DELETE.

  4. Check your library's auto-fields — disable or exclude auto-managed attributes (timestamps, versions) from updates where your own expression already writes them.

  5. Split into two requests when you genuinely need "replace parent, then tweak child" semantics — two UpdateItem calls, in order.

Editing nested maps by hand is where overlaps sneak in — the DynoTable desktop app edits an item's attributes in place and issues a clean, non-overlapping update for exactly what changed.

Reproduce it

One UpdateExpression setting both a map and a field inside that same map:

await client.send(
  new UpdateItemCommand({
    TableName: 'orders',
    Key: {pk: {S: 'ORDER#1'}, sk: {S: 'META'}},
    UpdateExpression: 'SET #a = :v, #a.#b = :w',
    ExpressionAttributeNames: {'#a': 'addr', '#b': 'city'},
    ExpressionAttributeValues: {':v': {M: {}}, ':w': {S: 'Berlin'}}
  })
);

Real output:

ValidationException: 1 validation error detected: Invalid UpdateExpression: Two document paths overlap with each other; must remove or rewrite one of these paths; path one: [addr], path two: [addr, city]
HTTP 400

The message prints both conflicting paths in full, so it tells you exactly which pair to reconcile. The order is undefined if both were applied, which is why DynamoDB refuses rather than picking one.

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Reproduced 2026-07-26 against DynamoDB Local 2.x with AWS SDK for JavaScript v3.1095.0 — the output above is verbatim.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.