-
Notifications
You must be signed in to change notification settings - Fork 634
Description
Checkboxes for prior research
- I've gone through Developer Guide and API reference
- I've checked AWS Forums and StackOverflow.
- I've searched for previous similar issues and didn't find any solution.
Describe the bug
When querying with DynamoDBDocumentClient
, if the attribute name (defined via ExpressionAttributeNames
) includes special characters like #
, the associated ExpressionAttributeValues
get marshalled twice.
This results in a malformed query, where the value is first wrapped as { S: value }
but then incorrectly wrapped again as a nested M
(map) structure.
This was observed using middleware to log the command input before and after marshalling.
Regression Issue
- Select this option if this issue appears to be a regression.
SDK version number
@aws-sdk/[email protected], @aws-sdk/[email protected]
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
Node version: 18.20.3
Reproduction Steps
- Use DynamoDBDocumentClient to send a QueryCommand
- Set ExpressionAttributeNames to include a key with special characters (e.g., customerId#upin)
Sample code:
`const {
DynamoDBClient
} = require('@aws-sdk/client-dynamodb');
const {
DynamoDBDocumentClient,
QueryCommand
} = require('@aws-sdk/lib-dynamodb');
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
async function query() {
const input = {
TableName: 'example-table',
KeyConditionExpression: '#key = :partitionKey',
ExpressionAttributeNames: {
'#key': 'firstName#lastName',
},
ExpressionAttributeValues: {
':partitionKey': 'abc#xyz',
},
Limit: 1,
ScanIndexForward: false,
};
const command = new QueryCommand(input);
command.middlewareStack.addRelativeTo(
(next) => async (args) => {
console.log('pre-marshall:', args.input);
return next(args);
},
{
relation: 'before',
toMiddleware: 'DocumentMarshall',
}
);
command.middlewareStack.addRelativeTo(
(next) => async (args) => {
console.log('post-marshall:', args.input);
return next(args);
},
{
relation: 'after',
toMiddleware: 'DocumentMarshall',
}
);
try {
await docClient.send(command);
} catch (err) {
console.error('Query failed:', err);
}
}
query();
`
Observed Behavior
Marshalling is happening twice when the key contains special characters.
Error log:
"One or more parameter values were invalid: Condition parameter type does not match schema type"
Below are the logs captured via middleware:
pre-marshall:
{
KeyConditionExpression: '#key = :partitionKey',
ExpressionAttributeValues: { ':partitionKey': '111#xyz' },
ExpressionAttributeNames: { '#key': 'customerId#upin' },
Limit: 1,
ScanIndexForward: false,
TableName: 'table'
}
post-marshall:
{
KeyConditionExpression: '#key = :partitionKey',
ExpressionAttributeValues: { ':partitionKey': { S: '111#xyz' } },
ExpressionAttributeNames: { '#key': 'customerId#upin' },
Limit: 1,
ScanIndexForward: false,
TableName: 'table'
}
Then marshalling happens again:
pre-marshall:
{
KeyConditionExpression: '#key = :partitionKey',
ExpressionAttributeValues: { ':partitionKey': { S: '111#xyz' } },
ExpressionAttributeNames: { '#key': 'customerId#upin' },
Limit: 1,
ScanIndexForward: false,
TableName: 'table'
}
post-marshall:
{
KeyConditionExpression: '#key = :partitionKey',
ExpressionAttributeValues: { ':partitionKey': { M: [Object] } },
ExpressionAttributeNames: { '#key': 'customerId#upin' },
Limit: 1,
ScanIndexForward: false,
TableName: 'table'
}
Expected Behavior
The value in ExpressionAttributeValues
should be marshalled only once, even if the corresponding attribute name contains special characters.
Possible Solution
No response
Additional Information/Context
No response