Description
Acknowledgements
- I have searched (https://github.com/aws/aws-sdk/issues?q=is%3Aissue) for past instances of this issue
- I have verified all of my SDK modules are up-to-date (you can perform a bulk update with
go get -u github.com/aws/aws-sdk-go-v2/...
)
Describe the bug
Description:
When constructing a ConditionExpression in the PutItem function of the DynamoDB client, the conditional expression doesn't behave as expected. The goal is to check if the OriginURL attribute exists and is not empty. However, despite constructing the conditional expression correctly, an error is returned from the API, indicating an issue with the expression attribute name used in the document path.
Code Sample
func (d *dynamoDBClient) PutItem(ctx context.Context, tableName string, entity any) (any, error) {
item, err := attributevalue.MarshalMap(entity)
if err != nil {
return nil, fmt.Errorf("failed to marshal item to DynamoDB attribute value: %w", err)
}
// Build a conditional expression to check if 'OriginURL' exists and is not empty.
conditionalBuilder := expression.Name("OriginURL").AttributeNotExists()
conditionalExpression, err := expression.NewBuilder().WithCondition(conditionalBuilder).Build()
if err != nil {
return nil, fmt.Errorf("failed to build conditional expression: %w", err)
}
//aws.String("attribute_not_exists((OriginURL))"),
// Set up PutItem input with conditional expression.
putItemInput := &dynamodb.PutItemInput{
Item: item,
TableName: aws.String(tableName),
ConditionExpression: conditionalExpression.Condition(),
ReturnValuesOnConditionCheckFailure: types.ReturnValuesOnConditionCheckFailureAllOld,
}
// Attempt to put the item into DynamoDB table.
response, err := d.dynamodbClient.PutItem(ctx, putItemInput)
if err != nil {
return nil, fmt.Errorf("failed to put item to DynamoDB: %w", err)
}
return entity, nil
}
Error Returned
operation error DynamoDB: PutItem, https response error StatusCode: 400, RequestID: 4bd9ca2f-753d-4e8a-ba27-526be7f5e6a0, api error ValidationException: Invalid ConditionExpression: An expression attribute name used in the document path is not defined; attribute name: #0
Expected Behavior
to build the condition expression like this attribute_not_exists((OriginURL))
Current Behavior
it makes the condition like this attribute_not_exists((#0))
which I think the substitution is wrong
Reproduction Steps
this this build expression expression.Name("Name").AttributeValues()
Possible Solution
The error indicates that there might be a bug in the SDK related to building the expression attribute name used in the document path. which I think in aliasPath
method under expression.go
func (al *aliasList) aliasPath(nm string) (string, error) {
for ind, name := range al.namesList {
if nm == name {
al.namesList = append(al.namesList, nm) # <---We should append name to the name list or break the for loop
return fmt.Sprintf("#%d", ind), nil
}
}
al.namesList = append(al.namesList, nm)
return fmt.Sprintf("#%d", len(al.namesList)-1), nil
}
Additional Information/Context
No response
AWS Go SDK V2 Module Versions Used
Yes
Compiler and Version used
go1.21.5
Operating System and version
MacOs
Activity