Bug: DynamoDB UpdateItem ignores legacy Expected conditions
Summary
In floci/floci:1.5.15, DynamoDB UpdateItem appears to ignore legacy Expected conditions.
When using the legacy Expected parameter, an UpdateItem request that should fail with ConditionalCheckFailedException succeeds instead. In the missing-item case, floci creates a new item without the attribute used in the Expected condition.
This differs from localstack/localstack:4.5, which returns ConditionalCheckFailedException for the same request.
Environment
- Image:
floci/floci:1.5.15
- Service: DynamoDB
- Region:
ap-northeast-1
- AWS CLI used for reproduction
Reproduction
Start floci:
docker run --rm -p 4566:4566 floci/floci:1.5.15
Create a table:
aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb create-table \
--table-name CODEX_FLOCI_EXPECTED_TEST \
--key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE \
--attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S \
--billing-mode PAY_PER_REQUEST
Run UpdateItem against a non-existent item with a legacy Expected condition:
aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb update-item \
--table-name CODEX_FLOCI_EXPECTED_TEST \
--key '{"PK":{"S":"k1"},"SK":{"S":"s1"}}' \
--expected '{"MEM_NO":{"ComparisonOperator":"EQ","Value":{"N":"1"}}}' \
--attribute-updates '{"SESSION_DATA":{"Action":"PUT","Value":{"S":"{}"}},"TTL_UTC":{"Action":"PUT","Value":{"N":"10000"}},"VERSION":{"Action":"ADD","Value":{"N":"1"}}}'
Expected behavior
The request should fail because MEM_NO does not exist on the target item.
Expected error:
ConditionalCheckFailedException
Actual behavior
The request succeeds.
The created item does not contain MEM_NO:
aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb get-item \
--table-name CODEX_FLOCI_EXPECTED_TEST \
--key '{"PK":{"S":"k1"},"SK":{"S":"s1"}}'
Actual item:
{
"Item": {
"PK": {
"S": "k1"
},
"SK": {
"S": "s1"
},
"SESSION_DATA": {
"S": "{}"
},
"TTL_UTC": {
"N": "10000"
},
"VERSION": {
"N": "1"
}
}
}
Additional case
The same issue also occurs when the item exists but the Expected value does not match.
Create an item with MEM_NO = 2:
aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb put-item \
--table-name CODEX_FLOCI_EXPECTED_TEST \
--item '{"PK":{"S":"k2"},"SK":{"S":"s1"},"MEM_NO":{"N":"2"}}'
Run UpdateItem with Expected MEM_NO == 1:
aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb update-item \
--table-name CODEX_FLOCI_EXPECTED_TEST \
--key '{"PK":{"S":"k2"},"SK":{"S":"s1"}}' \
--expected '{"MEM_NO":{"ComparisonOperator":"EQ","Value":{"N":"1"}}}' \
--attribute-updates '{"SESSION_DATA":{"Action":"PUT","Value":{"S":"{}"}},"TTL_UTC":{"Action":"PUT","Value":{"N":"10000"}},"VERSION":{"Action":"ADD","Value":{"N":"1"}}}'
Expected:
ConditionalCheckFailedException
Actual:
The request succeeds.
Comparison with LocalStack
The same reproduction against localstack/localstack:4.5 correctly fails with:
An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed
Note
ConditionExpression appears to work correctly in floci 1.5.15.
This request correctly fails with ConditionalCheckFailedException:
aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb update-item \
--table-name CODEX_FLOCI_EXPECTED_TEST \
--key '{"PK":{"S":"k3"},"SK":{"S":"s1"}}' \
--condition-expression 'MEM_NO = :memberNumber' \
--expression-attribute-values '{":memberNumber":{"N":"1"},":data":{"S":"{}"},":ttl":{"N":"10000"},":inc":{"N":"1"}}' \
--update-expression 'SET SESSION_DATA = :data, TTL_UTC = :ttl ADD VERSION :inc'
Result:
ConditionalCheckFailedException
Impact
Applications using AWS SDK v1 may still emit legacy Expected conditions. In our case, this caused tests that pass on LocalStack to fail on floci because UpdateItem unexpectedly created/updated items that should have been rejected by the condition.
Bug: DynamoDB UpdateItem ignores legacy
ExpectedconditionsSummary
In
floci/floci:1.5.15, DynamoDBUpdateItemappears to ignore legacyExpectedconditions.When using the legacy
Expectedparameter, anUpdateItemrequest that should fail withConditionalCheckFailedExceptionsucceeds instead. In the missing-item case, floci creates a new item without the attribute used in theExpectedcondition.This differs from
localstack/localstack:4.5, which returnsConditionalCheckFailedExceptionfor the same request.Environment
floci/floci:1.5.15ap-northeast-1Reproduction
Start floci:
Create a table:
Run
UpdateItemagainst a non-existent item with a legacyExpectedcondition:Expected behavior
The request should fail because
MEM_NOdoes not exist on the target item.Expected error:
Actual behavior
The request succeeds.
The created item does not contain
MEM_NO:aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb get-item \ --table-name CODEX_FLOCI_EXPECTED_TEST \ --key '{"PK":{"S":"k1"},"SK":{"S":"s1"}}'Actual item:
{ "Item": { "PK": { "S": "k1" }, "SK": { "S": "s1" }, "SESSION_DATA": { "S": "{}" }, "TTL_UTC": { "N": "10000" }, "VERSION": { "N": "1" } } }Additional case
The same issue also occurs when the item exists but the
Expectedvalue does not match.Create an item with
MEM_NO = 2:aws --region ap-northeast-1 --endpoint-url http://localhost:4566 dynamodb put-item \ --table-name CODEX_FLOCI_EXPECTED_TEST \ --item '{"PK":{"S":"k2"},"SK":{"S":"s1"},"MEM_NO":{"N":"2"}}'Run
UpdateItemwithExpected MEM_NO == 1:Expected:
Actual:
The request succeeds.
Comparison with LocalStack
The same reproduction against
localstack/localstack:4.5correctly fails with:Note
ConditionExpressionappears to work correctly in floci 1.5.15.This request correctly fails with
ConditionalCheckFailedException:Result:
Impact
Applications using AWS SDK v1 may still emit legacy
Expectedconditions. In our case, this caused tests that pass on LocalStack to fail on floci becauseUpdateItemunexpectedly created/updated items that should have been rejected by the condition.