ValidationException: ExpressionAttributeValues contains invalid value

TL;DR — Une valeur de ExpressionAttributeValues est vide, a un type non pris en charge, ou un :placeholder utilisé dans ton expression n'a jamais été défini. Vérifie que chaque :value est présente et non vide.

Ce que ça signifie

Messages courants :

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: keys: {:x}
ValidationException: An expression attribute value used in expression is not defined; attribute value: :v

Pourquoi ça arrive

  • Chaîne vide / binaire vide — historiquement DynamoDB rejetait "". Les chaînes vides sont désormais autorisées pour les attributs non-clé (et les Lists/Maps vides sont acceptées), mais les valeurs vides dans les attributs clé et les Sets vides restent invalides.
  • Placeholder non défini — ton expression référence :v mais ExpressionAttributeValues n'a pas de :v.
  • Placeholder inutilisé — tu as défini :x mais aucune expression ne l'utilise (DynamoDB rejette toute la requête).
  • Mauvais type — passer un objet JS brut/undefined/NaN, ou (avec le client bas niveau) le mauvais wrapper {S}/{N}.
  • Un set vide passé à une opération ADD/DELETE — ces clauses prennent des opérandes de type set (ou, pour ADD, number), et un set ne peut jamais être vide.

Comment le corriger

  1. Chaque :value de l'expression doit être définie dans ExpressionAttributeValues, et chaque valeur définie doit être utilisée — garde les deux exactement synchronisées.
  2. Protège-toi contre les valeurs vides/undefined. Ne passe pas :v quand la source est undefined ; supprime plutôt la clause. Pour les sets, garantis au moins un membre.
  3. Utilise le Document Client (@aws-sdk/lib-dynamodb) pour que les valeurs JS natives soient marshalled à ta place — il élimine la plupart des erreurs de wrapper de type.

Exemple

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
  })
);

Chemin dans DynoTable

L'éditeur de mise à jour de DynoTable lie les valeurs à mesure que tu tapes et rejette les placeholders vides avant que la requête ne quitte ta machine. Ouvre l'élément avec ⌘K, modifie un champ, et inspecte la map ExpressionAttributeValues générée dans l'aperçu de requête — les incohérences apparaissent tout de suite, au lieu d'un 400 dans CloudWatch.

Pour du code SDK que tu ne peux pas exécuter à la volée, colle l'expression dans l'Expression Builder et compare sa map :value à la tienne. Change de profil avec ⌘P pour tester contre la table même qui a levé l'erreur ; Test Connection dans Settings → Profiles confirme les identifiants et la région. Configuration : Se connecter à AWS, Installation. Les ensembles vides et les valeurs JS undefined sont les causes les plus fréquentes — protège-toi des deux avant que l'appel ne quitte ton processus.

Sources

Erreurs liées

Références

Dernière vérification le 2026-07-13 par rapport à la documentation officielle AWS liée ci-dessus.

Travaille avec DynamoDB sans la Console

Un client de bureau rapide pour DynamoDB qui exécute le vrai SQL que DynamoDB ne peut pas — JOINs, GROUP BY, agrégations — avec édition visuelle et un agent IA sur tes propres clés Bedrock.

Essai gratuit de 30 jours, sans carte bancaire — ensuite la formule Gratuit, sans limite de durée.