ExpressionAttributeNames contains invalid key: Syntax error
TL;DR — Das Problem ist der Platzhalter-Schlüssel auf der linken Seite deiner ExpressionAttributeNames-Map, nicht das Attribut, auf das er zeigt. Ein Platzhalter muss # gefolgt von einfachen Buchstaben, Ziffern oder Unterstrichen sein (#name, #p0). Wenn du den echten Attributnamen — mit seinen Punkten, Bindestrichen, +-Zeichen oder Leerzeichen — in den Platzhalter selbst schreibst, weist DynamoDB die Map zurück. Halte Platzhalter langweilig; setze den chaotischen echten Namen auf die rechte Seite.
Was es bedeutet
ValidationException: ExpressionAttributeNames contains invalid key:
Syntax error; key: "#my.attribute"ExpressionAttributeNames bildet ein Platzhalter-Token (das du innerhalb deiner Expression verwendest) auf einen echten Attributnamen ab. DynamoDB validiert die Syntax des Platzhalters, bevor es deine Daten anfasst: er muss mit # beginnen und darf nur Zeichen enthalten, die innerhalb eines Expression-Tokens gültig sind. Sonderzeichen, die in der Expression-Grammatik eine Bedeutung haben — . (Pfadtrenner), -, +, Leerzeichen — machen den Platzhalter selbst unparsbar, und die gesamte Anfrage wird mit dieser ValidationException zurückgewiesen.
Warum es passiert
- Der echte Attributname wurde in den Platzhalter kopiert — z. B.
{"#stats.daily": "stats.daily"}. Der Punkt im Schlüssel ist ein Syntaxfehler, egal worauf er abbildet. - Sonderzeichen im Platzhalter — Bindestriche (
#user-id),+-Zeichen oder Leerzeichen. Nur alphanumerische Zeichen und Unterstriche sind nach dem#sicher. - Ein fehlendes
#— Schlüssel inExpressionAttributeNamesmüssen mit#beginnen;{"name": "name"}ist ungültig. - Eine Bibliothek, die Platzhalter aus Attributnamen automatisch generiert, die Punkte oder Sonderzeichen enthalten, und das Zeichen direkt durchreicht.
Wie du es behebst
Verwende einfache Platzhalter und bilde jeden auf den echten Namen ab:
{ ExpressionAttributeNames: {'#p0': 'user-id', '#p1': 'stats'}, KeyConditionExpression: '#p0 = :uid' }Für verschachtelte Pfade aliasiere jedes Segment einzeln — einen Platzhalter pro Pfadelement, verbunden durch einen literalen Punkt in der Expression:
// read stats.daily where the item has a top-level "stats" map { ProjectionExpression: '#s.#d', ExpressionAttributeNames: {'#s': 'stats', '#d': 'daily'} }Beachte die Kehrseite: Wenn der tatsächliche Name des Attributs einen literalen Punkt enthält (ein Attribut namens
"stats.daily", kein verschachtelter Pfad), ist ein einzelner Platzhalter für den ganzen Namen genau das Richtige —{'#sd': 'stats.daily'}— sodass der Punkt als Teil des Namens behandelt wird, nicht als Pfadtrenner.Prüfe, was dein Wrapper generiert — wenn ein ODM/Helper die Map für dich baut, logge die endgültige Anfrage und inspiziere die Platzhalter-Schlüssel, die er erzeugt hat.
Arbeitest du mit Attributen, deren Namen voller Punkte und Bindestriche sind? Die DynoTable-Desktop-App baut ihre Abfragen automatisch mit korrekt aliasierten Namen, egal wie das Attribut heißt.
Verwandte Fehler
- Attribute name is a reserved keyword — der andere große Grund,
ExpressionAttributeNameszu verwenden. - Value provided in ExpressionAttributeNames unused in expressions
- Value provided in ExpressionAttributeValues unused
- Learn: Expression names & values
References
- Expression attribute names (aliases) in DynamoDB — Amazon DynamoDB Developer Guide
- Query — Amazon DynamoDB API Reference
- Reserved words in DynamoDB — Amazon DynamoDB Developer Guide
Zuletzt verifiziert am 2026-07-13 gegen die offizielle, oben verlinkte AWS-Dokumentation.