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: 1 validation error detected: Value provided in ExpressionAttributeNames unused in
expressions: keys: {#status}
# what the engine actually returns, reproduced against DynamoDB Local:
ValidationException: 1 validation error detected: 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.
Inspect in DynoTable
DynoTable aliases reserved attribute names in the update and filter editors — every #placeholder in the output is referenced in the expression. Open a table with ⌘K, edit an item, and copy the generated ExpressionAttributeNames map.
Cross-check failing SDK requests in the reserved words checker — it prints the alias map for names that need # prefixes. Switch profiles with ⌘P; see Connect to AWS and Install.
Sources
- Expression attribute names (aliases) in DynamoDB (verified 2026-07-13)
- Reserved words in DynamoDB (verified 2026-07-13)
Reproduce it
An ExpressionAttributeNames entry that no expression references:
await client.send(
new UpdateItemCommand({
TableName: 'orders',
Key: {pk: {S: 'ORDER#1'}, sk: {S: 'META'}},
UpdateExpression: 'SET stat = :v', // note: 'stat', not '#unused'
ExpressionAttributeNames: {'#unused': 'status'},
ExpressionAttributeValues: {':v': {S: 'shipped'}}
})
);Real output:
ValidationException: 1 validation error detected: Value provided in ExpressionAttributeNames unused in expressions: keys: {#unused}
HTTP 400The message names the offending key, which makes this one of the few DynamoDB validation errors you can act on without reading anything else. It usually appears after an edit removes a placeholder from the expression but leaves its declaration behind.
Related errors
- Value provided in ExpressionAttributeValues unused in expressions — the same rule for
:valueplaceholders. - The provided expression refers to an attribute that does not exist in the item — the expression reads an item attribute that isn't there.
- Attribute name is a reserved keyword — why you needed a
#-alias in the first place. - 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
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.