{"record":{"id":"2eec1ec26fdfde2d","repo":"t8y2/dbx","slug":"validated-dynamodb-put-item","errorCode":null,"errorMessage":"validated DynamoDB put item","messagePattern":"validated DynamoDB put item","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbx-core/src/db/dynamodb_driver.rs","lineNumber":382,"sourceCode":"                filter.as_deref(),\n                sort.as_deref(),\n                statement.cursor.as_deref(),\n            )\n            .await?;\n            Ok(document_query_result(result, started))\n        }\n        DynamoDbStatementOperation::Insert => {\n            let key = serde_json::to_string(statement.key.as_ref().expect(\"validated DynamoDB insert key\"))\n                .map_err(|error| error.to_string())?;\n            let item = serde_json::to_string(statement.item.as_ref().expect(\"validated DynamoDB insert item\"))\n                .map_err(|error| error.to_string())?;\n            insert_item_with_expected_identity(client, &statement.table, &item, Some(&key)).await?;\n            Ok(affected_query_result(1, started))\n        }\n        DynamoDbStatementOperation::Put => {\n            let key = serde_json::to_string(statement.key.as_ref().expect(\"validated DynamoDB put key\"))\n                .map_err(|error| error.to_string())?;\n            let item = serde_json::to_string(statement.item.as_ref().expect(\"validated DynamoDB put item\"))\n                .map_err(|error| error.to_string())?;\n            let affected = update_item(client, &statement.table, &key, &item).await?;\n            Ok(affected_query_result(affected, started))\n        }\n        DynamoDbStatementOperation::Delete => {\n            let key = serde_json::to_string(statement.key.as_ref().expect(\"validated DynamoDB delete key\"))\n                .map_err(|error| error.to_string())?;\n            let affected = delete_item(client, &statement.table, &key).await?;\n            Ok(affected_query_result(affected, started))\n        }\n    }\n}\n\nfn parse_dynamodb_statement(source: &str) -> Result<DynamoDbStatement, String> {\n    let mut lines = source.lines();\n    let header = lines\n        .find(|line| !line.trim().is_empty())\n        .map(str::trim)","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/crates/dbx-core/src/db/dynamodb_driver.rs#L364-L400","documentation":"Panic from `Option::expect` on `statement.item` when serializing the item for a DynamoDB Put statement. The validation layer must guarantee an item exists for Puts; a None here means an unvalidated statement reached the driver and the process aborts. It is an internal invariant failure, not a user-facing data error.","triggerScenarios":"Executing DynamoDbStatementOperation::Put with item = None, typically from statements assembled in code or deserialized without running parse_dynamodb_statement validation.","commonSituations":"Building put statements programmatically; forwarding raw user JSON to the driver; test fixtures without items; validation logic lost in refactors.","solutions":["Always parse/validate Put statements via parse_dynamodb_statement before execution","Verify statement.item.is_some() before calling execute_statement for Put","Convert the expect into ok_or_else returning a clear error string","Add a regression test for an itemless Put statement"],"exampleFix":"// before\nlet item = serde_json::to_string(statement.item.as_ref().expect(\"validated DynamoDB put item\"))\n    .map_err(|error| error.to_string())?;\n// after\nlet item_src = statement.item.as_ref()\n    .ok_or_else(|| \"DynamoDB put statement requires an item\".to_string())?;\nlet item = serde_json::to_string(item_src).map_err(|error| error.to_string())?;","handlingStrategy":"validation","validationCode":"if stmt.operation == DynamoDbStatementOperation::Put && stmt.item.is_none() {\n    return Err(\"DynamoDB put statement requires an item\".into());\n}","typeGuard":"fn has_dynamodb_item(stmt: &Statement) -> bool {\n    stmt.item.is_some()\n}","tryCatchPattern":"match driver.execute_statement(stmt).await {\n    Ok(r) => r,\n    Err(e) => { log::error!(\"put failed: {e}\"); return Err(e); }\n}","preventionTips":["Construct Put statements only through the statement parser","Check item presence before submitting write batches","Keep statement deserialization and validation coupled"],"tags":["rust","dynamodb","panic","invariant-violation"],"backgroundTag":"internal-invariant-panic","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}