{"record":{"id":"93a8dc3813f51ecc","repo":"tursodatabase/turso","slug":"invalid-drop-behavior-value","errorCode":null,"errorMessage":"Invalid drop behavior: {value}","messagePattern":"Invalid drop behavior: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bindings/rust/src/transaction.rs","lineNumber":72,"sourceCode":"impl From<DropBehavior> for u8 {\n    fn from(behavior: DropBehavior) -> Self {\n        match behavior {\n            DropBehavior::Rollback => 0,\n            DropBehavior::Commit => 1,\n            DropBehavior::Ignore => 2,\n            DropBehavior::Panic => 3,\n        }\n    }\n}\n\nimpl From<u8> for DropBehavior {\n    fn from(value: u8) -> Self {\n        match value {\n            0 => DropBehavior::Rollback,\n            1 => DropBehavior::Commit,\n            2 => DropBehavior::Ignore,\n            3 => DropBehavior::Panic,\n            _ => panic!(\"Invalid drop behavior: {value}\"),\n        }\n    }\n}\n\n/// Represents a transaction on a database connection.\n///\n/// ## Note\n///\n/// Transactions will roll back by default. Use `commit` method to explicitly\n/// commit the transaction, or use `set_drop_behavior` to change what happens\n/// on the next access to the connection after the transaction is dropped.\n///\n/// ## Example\n///\n/// ```rust,no_run\n/// # use turso::{Connection, Result};\n/// # fn do_queries_part_1(_conn: &Connection) -> Result<()> { Ok(()) }\n/// # fn do_queries_part_2(_conn: &Connection) -> Result<()> { Ok(()) }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/rust/src/transaction.rs#L54-L90","documentation":"DropBehavior has exactly four variants encoded as 0..=3 (Rollback=0, Commit=1, Ignore=2, Panic=3). From<u8> panics for any other byte, guarding the u8 representation stored on the connection (the dangling_tx AtomicU8) against out-of-range values.","triggerScenarios":"DropBehavior::from(byte) with byte >= 4: decoding a corrupt byte from the atomic slot, an FFI/deserialization caller passing an arbitrary integer, or tests constructing the enum from raw bytes.","commonSituations":"Serialization format drift between binding versions; hand-written FFI glue mapping C ints to the enum; fuzzed input reaching the conversion.","solutions":["Validate the byte is <= 3 before calling from()","Fix the producer (FFI shim, persisted format) to only emit 0..=3","Match on the byte yourself at the boundary and return an error for unknown values instead of panicking"],"exampleFix":"// before\nlet behavior = DropBehavior::from(raw); // panics if raw > 3\n\n// after\nlet behavior = match raw {\n    0 => DropBehavior::Rollback,\n    1 => DropBehavior::Commit,\n    2 => DropBehavior::Ignore,\n    3 => DropBehavior::Panic,\n    other => return Err(format!(\"invalid drop behavior byte {other}\")),\n};","handlingStrategy":"type-guard","validationCode":"if raw > 3 {\n    return Err(anyhow!(\"invalid DropBehavior byte {raw}\"));\n}\nlet behavior = DropBehavior::from(raw);","typeGuard":"pub fn is_valid_drop_behavior(raw: u8) -> bool {\n    matches!(raw, 0 | 1 | 2 | 3)\n}","tryCatchPattern":null,"preventionTips":["Range-check integers at FFI/serialization boundaries before converting to enums","Keep enum-to-integer mappings in one place so producers stay in sync"],"tags":["rust","enum","deserialization","panic","input-validation"],"backgroundTag":"invalid-enum-discriminant","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}