t8y2/dbx · error

validated DynamoDB delete key

Error message

validated DynamoDB delete key

What it means

Panic from `Option::expect` on `statement.key` when serializing the key for a DynamoDB Delete statement. Deletes must target an explicit key guaranteed by validation; a None key reaching this code means the parser/validation step was bypassed and the process panics. This is an internal contract violation rather than a DynamoDB error.

Source

Thrown at crates/dbx-core/src/db/dynamodb_driver.rs:388

        }
        DynamoDbStatementOperation::Insert => {
            let key = serde_json::to_string(statement.key.as_ref().expect("validated DynamoDB insert key"))
                .map_err(|error| error.to_string())?;
            let item = serde_json::to_string(statement.item.as_ref().expect("validated DynamoDB insert item"))
                .map_err(|error| error.to_string())?;
            insert_item_with_expected_identity(client, &statement.table, &item, Some(&key)).await?;
            Ok(affected_query_result(1, started))
        }
        DynamoDbStatementOperation::Put => {
            let key = serde_json::to_string(statement.key.as_ref().expect("validated DynamoDB put key"))
                .map_err(|error| error.to_string())?;
            let item = serde_json::to_string(statement.item.as_ref().expect("validated DynamoDB put item"))
                .map_err(|error| error.to_string())?;
            let affected = update_item(client, &statement.table, &key, &item).await?;
            Ok(affected_query_result(affected, started))
        }
        DynamoDbStatementOperation::Delete => {
            let key = serde_json::to_string(statement.key.as_ref().expect("validated DynamoDB delete key"))
                .map_err(|error| error.to_string())?;
            let affected = delete_item(client, &statement.table, &key).await?;
            Ok(affected_query_result(affected, started))
        }
    }
}

fn parse_dynamodb_statement(source: &str) -> Result<DynamoDbStatement, String> {
    let mut lines = source.lines();
    let header = lines
        .find(|line| !line.trim().is_empty())
        .map(str::trim)
        .ok_or_else(|| "DynamoDB statement is empty".to_string())?;
    let operation = match header.to_ascii_uppercase().as_str() {
        "DBX DYNAMODB SCAN" | "DBX DYNAMODB QUERY / SCAN" => DynamoDbStatementOperation::Read,
        "DBX DYNAMODB INSERT ITEM" => DynamoDbStatementOperation::Insert,
        "DBX DYNAMODB PUT ITEM" => DynamoDbStatementOperation::Put,
        "DBX DYNAMODB DELETE ITEM" => DynamoDbStatementOperation::Delete,

View on GitHub (pinned to c0390bff16)

Solutions

  1. Create Delete statements only through parse_dynamodb_statement so key validation runs
  2. Guard with statement.key.is_some() before executing a Delete
  3. Replace expect with ok_or_else to return a recoverable 'delete requires a key' error
  4. Add a unit test that a keyless Delete fails validation cleanly

Example fix

// before
let key = serde_json::to_string(statement.key.as_ref().expect("validated DynamoDB delete key"))
    .map_err(|error| error.to_string())?;
// after
let key_src = statement.key.as_ref()
    .ok_or_else(|| "DynamoDB delete statement requires a key".to_string())?;
let key = serde_json::to_string(key_src).map_err(|error| error.to_string())?;
Defensive patterns

Strategy: validation

Validate before calling

if stmt.operation == DynamoDbStatementOperation::Delete && stmt.key.is_none() {
    return Err("DynamoDB delete statement requires a key".into());
}

Type guard

fn is_deletable(stmt: &Statement) -> bool {
    stmt.operation == DynamoDbStatementOperation::Delete && stmt.key.is_some()
}

Try / catch

let affected = driver.execute_statement(stmt).await.map_err(|e| { eprintln!("delete failed: {e}"); e })?;

Prevention

When it happens

Trigger: Calling execute_statement with DynamoDbStatementOperation::Delete and key = None — hand-built statements, externally supplied statement JSON that skipped validation, or a dropped validation branch.

Common situations: Programmatic delete construction; proxying user statements straight to the driver; incomplete test fixtures; refactors removing key validation for deletes.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/d5699dd39ed7361c. Report an issue: GitHub.