Value provided in ExpressionAttributeNames unused in expressions
TL;DR — You declared a name placeholder in ExpressionAttributeNames (e.g. #status) that no expression references. DynamoDB requires every declared alias to be used in a KeyConditionExpression, FilterExpression, UpdateExpression, ConditionExpression, or ProjectionExpression. Remove the unused alias — or fix the expression that was supposed to reference it.
What it means
ValidationException: Value provided in ExpressionAttributeNames unused in
expressions: keys: {#status}ExpressionAttributeNames is a substitution map for attribute-name aliases (needed for reserved words or names with special characters). DynamoDB enforces a strict two-way contract: every alias you use in an expression must be declared, and every alias you declare must be used. A leftover, unreferenced entry triggers this HTTP 400 ValidationException. It's client-side and not retryable until the map matches the expressions.
Why it happens
- A stale alias left after editing an expression — you removed
#status = :sfrom the expression but forgot to delete#statusfrom the names map. - A generated map that over-declares — a mapping layer emitted aliases for every attribute even ones the final expression doesn't touch.
- The alias is in the values map, not names — you meant
:status(a value) but declared#status(a name). - A typo mismatch — the expression uses
#statwhile the map declares#status, so#statusis technically unused.
How to fix it
- Delete the unused alias the message names from
ExpressionAttributeNames. - Keep the map in lock-step with the expressions — declare a
#nameonly when an expression actually references it. - Check for a name-vs-value mix-up —
#-aliases live inExpressionAttributeNames,:-placeholders inExpressionAttributeValues. - Regenerate the request so names, values, and expression text are built together rather than assembled by hand.
Related errors
- Value provided in ExpressionAttributeValues unused in expressions — the same rule for
:valueplaceholders. - An expression attribute name used in the document path is not defined — the reverse: a used alias that was never declared.
- Attribute name is a reserved keyword — why you needed a
#-alias in the first place.