ValidationException: ExpressionAttributeValues contains invalid value

TL;DR — A value in ExpressionAttributeValues is empty, has an unsupported type, or a :placeholder used in your expression was never defined. Check every :value is present and non-empty.

What it means

Common messages:

ValidationException: ExpressionAttributeValues contains invalid value: One or more parameter values were invalid: An AttributeValue may not contain an empty string for key :s
ValidationException: Value provided in ExpressionAttributeValues unused in expressions: key :x
ValidationException: An expression attribute value used in expression is not defined; attribute value: :v

Why it happens

  • Empty string / empty binary — historically DynamoDB rejected "". Empty strings are now allowed for non-key attributes, but empty values in key attributes and empty Sets are still invalid.
  • Undefined placeholder — your expression references :v but ExpressionAttributeValues has no :v.
  • Unused placeholder — you defined :x but no expression uses it (DynamoDB rejects the whole request).
  • Wrong type — passing a raw JS object/undefined/NaN, or (with the low-level client) the wrong {S}/{N} wrapper.
  • Empty list/map where a non-empty value is required by your ADD/DELETE set operation.

How to fix it

  1. Every :value in the expression must be defined in ExpressionAttributeValues, and every defined value must be used — keep the two in exact sync.
  2. Guard against empty/undefined. Don't pass :v when the source is undefined; drop the clause instead. For sets, ensure at least one member.
  3. Use the Document Client (@aws-sdk/lib-dynamodb) so native JS values are marshalled for you — it removes most type-wrapper mistakes.

Example

import {DynamoDBClient} from '@aws-sdk/client-dynamodb';
import {DynamoDBDocumentClient, UpdateCommand} from '@aws-sdk/lib-dynamodb';

const doc = DynamoDBDocumentClient.from(new DynamoDBClient({}));

const email = getEmail(); // could be undefined
const names = {'#e': 'email'};
const values = {':e': email};

if (email == null) throw new Error('email required'); // don't send :e = undefined

await doc.send(
  new UpdateCommand({
    TableName: 'Users',
    Key: {pk: 'USER#1'},
    UpdateExpression: 'SET #e = :e',
    ExpressionAttributeNames: names,
    ExpressionAttributeValues: values
  })
);

Travaille avec DynamoDB sans la Console

DynoTable est un client de bureau rapide pour DynamoDB — parcours les tables, exécute des requêtes de style SQL et édite les items en local.