Skip to content

Building ConditionExpression using expression package Doesn't Behave as Expected #2542

Closed
@msharbaji

Description

Acknowledgements

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions