t8y2/dbx · error

validated DynamoDB put key

Error message

validated DynamoDB put key

What it means

Panic from `Option::expect` on `statement.key` for a DynamoDB Put (upsert) statement. Put, like Insert, requires an explicit key that validation is supposed to guarantee; a None key reaching this line means validation was bypassed and the process panics. It is an internal contract violation, not a DynamoDB service error.

Source

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

                &statement.table,
                effective_limit,
                filter.as_deref(),
                sort.as_deref(),
                statement.cursor.as_deref(),
            )
            .await?;
            Ok(document_query_result(result, started))
        }
        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

View on GitHub (pinned to c0390bff16)

Solutions

  1. Construct Put statements only via parse_dynamodb_statement, which enforces explicit keys for writes
  2. Check statement.key.is_some() before invoking execute_statement for Put
  3. Replace expect with ok_or_else to surface a recoverable 'put requires a key' error
  4. Cover keyless Put in unit tests to lock in the validation

Example fix

// before
let key = serde_json::to_string(statement.key.as_ref().expect("validated DynamoDB put key"))
    .map_err(|error| error.to_string())?;
// after
let key_src = statement.key.as_ref()
    .ok_or_else(|| "DynamoDB put 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::Put && stmt.key.is_none() {
    return Err("DynamoDB put statement requires a key".into());
}

Type guard

fn has_explicit_key(stmt: &Statement) -> bool {
    matches!(stmt.operation, DynamoDbStatementOperation::Insert | DynamoDbStatementOperation::Put | DynamoDbStatementOperation::Delete)
        .implies(stmt.key.is_some())
}

Try / catch

driver.execute_statement(stmt).await.unwrap_or_else(|e| { eprintln!("put failed: {e}"); fallback_result() })

Prevention

When it happens

Trigger: Calling execute_statement with DynamoDbStatementOperation::Put and key = None — e.g. statements built in code, loaded from external JSON, or a code path where the put-key validation was skipped (rejects_write_statement_without_explicit_key not run).

Common situations: Programmatic statement construction; bypassing the parser when proxying user statements; test fixtures missing keys; regression after refactoring statement validation.

Related errors


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