aws-sdk-js-v3: client-dynamodb/lib-dynamodb v3.428.0: Sending an UpdateCommand fails with TypeError
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
Since v3.428.0 updates on a DynamoDB table fail with a TypeError. It worked up to v3.427.0. The call of new UpdateCommand(...)
is ok, but sending the call to DynamoDB fails. The properties of the UpdateCommand
result are different between v3.428.0 and v3.427.0, which may lead to this error.
SDK version number
@aws-sdk/lib-dynamodb@3.428.0
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
Node.js 18.x
Reproduction Steps
let UpdateExpression = "SET autoDeployEnabled = :autoDeployEnabled";
if (args.config.manualDeploymentInfo !== undefined) {
UpdateExpression += ", manualDeploymentInfo = :manualDeploymentInfo";
}
const cmd = new UpdateCommand({
ExpressionAttributeValues: {
":autoDeployEnabled": args.config.autoDeployEnabled,
":manualDeploymentInfo": args.config.manualDeploymentInfo,
},
Key: { dataItemType: TestDeploymentDataItemType, repoName: args.repoName },
ReturnValues: "ALL_NEW",
TableName: GlobalConstants.DataItemsTableName,
UpdateExpression,
});
const result = await DynamoDBDocumentClient.send(cmd);
Observed Behavior
The call await DynamoDBDocumentClient.send(cmd)
fails with a TypeError:
TypeError: Cannot read properties of undefined (reading 'S')
at AttributeValue.visit (node_modules/@aws-sdk/client-dynamodb/dist-cjs/models/models_0.js:620:19)
at se_AttributeValue (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:2948:38)
at [path_redacted]/node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:3151:20
at Array.reduce (<anonymous>)
at se_ExpressionAttributeValueMap (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:3147:34)
at ExpressionAttributeValues (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:3535:43)
at applyInstruction (node_modules/@smithy/smithy-client/dist-cjs/object-mapping.js:73:33)
at take (node_modules/@smithy/smithy-client/dist-cjs/object-mapping.js:44:9)
at se_UpdateItemInput (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:3529:37)
at se_UpdateItemCommand (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:357:27)
Expected Behavior
The call doesn’t fail. It didn’t fail with prior versions of client-dynamodb/lib-dynamodb.
Possible Solution
No response
Additional Information/Context
The properties inputKeyNodes
and outputKeyNodes
of the created UpdateCommand
(variable cmd
; see above) differ:
v3.427.0
"inputKeyNodes": [
{ "key": "Key" },
{
"key": "AttributeUpdates",
"children": { "children": [{ "key": "Value" }] }
},
{
"key": "Expected",
"children": {
"children": [{ "key": "Value" }, { "key": "AttributeValueList" }]
}
},
{ "key": "ExpressionAttributeValues" }
],
"outputKeyNodes": [
{ "key": "Attributes" },
{
"key": "ItemCollectionMetrics",
"children": [{ "key": "ItemCollectionKey" }]
}
],
with v3.428.0
"inputKeyNodes": {
"Key": {},
"AttributeUpdates": { "*": { "Value": null } },
"Expected": { "*": { "Value": null, "AttributeValueList": [] } },
"ExpressionAttributeValues": {}
},
"outputKeyNodes": {
"Attributes": {},
"ItemCollectionMetrics": { "ItemCollectionKey": {} }
},
inputKeyNodes
and outputKeyNodes
where changed/touched in this PR https://github.com/aws/aws-sdk-js-v3/pull/5306 (fix(lib-dynamodb): add e2e suite and bug fixes for lib-dynamodb)
About this issue
- Original URL
- State: closed
- Created 9 months ago
- Reactions: 8
- Comments: 15 (6 by maintainers)
Commits related to this issue
- ci: force version until https://github.com/aws/aws-sdk-js-v3/issues/5360 is resolved — committed to loopingz/webda.io by loopingz 9 months ago
The root Item is not marshalled because if it were, it would be sent as a Map:
native JS input
marshall if
Item=AttributeValue
(incorrect)corrected marshalling with
Item.*=AttributeValue
The reason this behavior changed is because the PR fixed the AttributeValue node indicators to more correctly target what fields are actual AttributeValues in need of conversion. However, as I mentioned above, I’ll try to add the top level filtering to be compatible with existing usage.
@ncino-esselman
It can’t marshal/marshall the column value of
undefined
because it doesn’t correspond to any DynamoDB AttributeValue type. The closest is NULL, i.e.{ NULL: true }
or omitting the column.{ S: undefined }
is not valid because the S is for string values.Undefined can be removed from maps and sets by the
removeUndefinedValues
marshallOptions flag, because that does not change the AttributeValue type of the map or set. But when it is the entire value, the column cannot be inserted. Currently the TypeError is based on the SDK being unable to serialize the unexpected undefined column value.Previously it worked because the marshall system incorrectly defined the entire Item as an AttributeValue and extracted its
M
value.@maplesteve if manualDeploymentInfo is a column value and can be undefined, you are likely facing the same issue, and the workarounds above are also advised in this case.
If you performing an insert, there is a patch upcoming in #5365 which will ignore undefined columns as before. However, if you are performing an update and want to set the column’s value from something to nothing, you should use a value of
null
instead. Setting an undefined column in an update will, even after the fix, at best be ignored, but will not overwrite the table data as you may intend.That makes sense! Thank you so much for your time and explanation! Also for the backwards compatibility change!!