Marshalled data returned from CallAwsService DynamoDB query has incorrect casing in type names
Describe the bug
When running the step function task CallAwsService to query a database in dynamodb, the returned items have incorrect casing in type names. More specifically, "BOOL" is returned as "Bool" which means the included unmarshall function throws an error
Expected Behavior
When running CallAwsService to query a db, it should return data in the form:
{
"Items": [
{
"example": {
"BOOL": true
}
}
]
}
Current Behavior
When running CallAwsService to query a db, it returns:
{
"Items": [
{
"example": {
"Bool": true
}
}
]
}
Reproduction Steps
The following step function:
{
"StartAt": "DBQuery",
"States": {
"DBQuery": {
"End": true,
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:dynamodb:query",
"Parameters": {
"TableName": "{tablename}",
"KeyConditionExpression": "#{key} = :{key}",
"ExpressionAttributeNames": {
"#{key}": "{key}"
},
"ExpressionAttributeValues": {
":scopeId": {
"S.$": "$.path.{key}"
}
},
"IndexName": "{indexname}"
}
}
},
"TimeoutSeconds": 300
}
Replacing tablename with an existing table, key with the partition key of a gsi, indexname with the name of a gsi on the table, giving it the necessary permissions, and running with payload:
{
"path": {
"{key}": "{value}"
}
}
Possible Solution
I imagine this should be a case of changing a hardcoded value from Bool to BOOL somewhere in the codebase, but if not, if the unmarshall function was able to deal with typenames insensitive of casing, that would also fix the problem
Additional Information/Context
No response
SDK version used
Unsure, probably latest
Environment details (OS name and version, etc.)
Called from a step function
Hey @Bee-Taylor thanks for opening this issue can you please share the code you are using and please confirm the version of the SDK as well?
Hi, so since this is calling SDK from step functions I'm not 100% sure if this is the right repo to ask this in, feel free to send me to a different repo if not
The dynamodb query operation is called from a step function defined in CDK, like:
return new CallAwsService(scope, `${id}-ddbQuery`, {
service: 'DynamoDB',
action: 'query',
parameters: {
TableName: table.tableName,
...parameters,
},
iamResources: [table.tableArn, ...(IndexName ? [`${table.tableArn}/index/${IndexName}`] : [])],
iamAction: 'dynamodb:Query',
})
Where Table is a dynamodb table, and indexname is the name of a gsi on that table
In terms of versions, these are my aws versions in package.json:
"aws-cdk": "^2.31.2",
"aws-cdk-lib": "^2.31.2",
"@aws-sdk/client-dynamodb": "^3.204.0",
"@aws-sdk/lib-dynamodb": "^3.204.0",
"@aws-sdk/util-dynamodb": "^3.204.0",
+1 for this, we just ran into it. Specifically when querying a DynamoDB table from the native step function action (resource arn:aws:states:::aws-sdk:dynamodb:query) we receive a marshalled DDB object in which top-level attributes are "BOOL" but any booleans nested in a map are "Bool".
We got around this by casting type/marshall attributes to uppercase in a custom implementation of the unmarshalling function.
Good god this is dumb. I have to write an intermediate layer to turn Bool to BOOL and Nul to NULL. Please fix this.
Step functions have enough quirks. This one is just ridiculous.
Here is my hack to fix this:
const cleanedPayload = JSON.stringify(payload)
.replace(/"Nul":/g, '"NULL":')
.replace(/"Bool":/g, '"BOOL":');
return unmarshall(JSON.parse(cleanedPayload));