Repository navigation
storage-cassandra: Query with an empty-string key condition value returns 500 #422
Description
Observed
Seen while reproducing #410 and pinned in the review probes for #416. A Query whose key condition value is an empty string returns HTTP 500 on the Cassandra server. The service returns 400. The answer is the same on main and on the #416 branch.
Measured on the service against a table with partition key pk (S), a GSI gs-index keyed on gs (S) and a GSI gn-index keyed on gn (N):
Query IndexName=gs-index KeyConditionExpression "gs = :v" :v = {"S": ""}
service: 400 ValidationException | One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: gs
Cassandra: 500 InternalServerError | Internal server error
Query IndexName=gn-index KeyConditionExpression "gn = :v" :v = {"S": ""} (wrong type for an N key)
service: 400 ValidationException | One or more parameter values were invalid: Condition parameter type does not match schema type
Cassandra: 500 InternalServerError | Internal server error
Query (table) KeyConditionExpression "pk = :v" :v = {"S": ""}
service: 400 ValidationException | One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: pk
Cassandra: 500 InternalServerError | Internal server error
Reading of the code
No code path emits the service's Key: <name> message for Query: the string does not appear in crates/core, crates/engine or any storage crate. The request reaches crates/storage-cassandra/src/data/query.rs with the empty value and fails inside the backend; the failing statement is not pinned yet. The read side was out of scope for #416, which covers UpdateItem and transaction writes.
SQLite, PostgreSQL and MongoDB were not measured in that review. Neither message string exists in their query paths either, so their answers need measuring before the fix is scoped.
Fix direction
Check key condition values in the engine before dispatch to any backend: the operand type against the key schema (Condition parameter type does not match schema type), then an empty string or binary (The AttributeValue for a key attribute cannot contain an empty string value. Key: <name>). One check serves all four backends and the per-backend query paths never see the value. Pin it with a dual-target wire test covering the table key, a string GSI, a numeric GSI and an LSI, run against the service and every backend.
Reproduce
aws dynamodb query --endpoint-url https://127.0.0.1:8000 --table-name t \
--index-name gs-index \
--key-condition-expression "gs = :v" \
--expression-attribute-values '{":v": {"S": ""}}'
Activity
jcshepherd commentedon Oct 22, 2026
#417
LeeroyHannigan commentedon Oct 25, 2026
Status against the open PRs: the wrong-type row (
gn = :vwith anSvalue on an N key) is fixed on every backend by the key schema type check in #544, which runs in the engine before storage. No open PR adds thecannot contain an empty string value. Key: <name>refusal forKeyConditionExpression; #507 adds it for legacyKeyConditionsonly. The empty-string rows here are still open.