tursodatabase/turso · error

Invalid drop behavior: {value}

Error message

Invalid drop behavior: {value}

What it means

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.

Source

Thrown at bindings/rust/src/transaction.rs:72

impl From<DropBehavior> for u8 {
    fn from(behavior: DropBehavior) -> Self {
        match behavior {
            DropBehavior::Rollback => 0,
            DropBehavior::Commit => 1,
            DropBehavior::Ignore => 2,
            DropBehavior::Panic => 3,
        }
    }
}

impl From<u8> for DropBehavior {
    fn from(value: u8) -> Self {
        match value {
            0 => DropBehavior::Rollback,
            1 => DropBehavior::Commit,
            2 => DropBehavior::Ignore,
            3 => DropBehavior::Panic,
            _ => panic!("Invalid drop behavior: {value}"),
        }
    }
}

/// Represents a transaction on a database connection.
///
/// ## Note
///
/// Transactions will roll back by default. Use `commit` method to explicitly
/// commit the transaction, or use `set_drop_behavior` to change what happens
/// on the next access to the connection after the transaction is dropped.
///
/// ## Example
///
/// ```rust,no_run
/// # use turso::{Connection, Result};
/// # fn do_queries_part_1(_conn: &Connection) -> Result<()> { Ok(()) }
/// # fn do_queries_part_2(_conn: &Connection) -> Result<()> { Ok(()) }

View on GitHub (pinned to c1e5928725)

Solutions

  1. Validate the byte is <= 3 before calling from()
  2. Fix the producer (FFI shim, persisted format) to only emit 0..=3
  3. Match on the byte yourself at the boundary and return an error for unknown values instead of panicking

Example fix

// before
let behavior = DropBehavior::from(raw); // panics if raw > 3

// after
let behavior = match raw {
    0 => DropBehavior::Rollback,
    1 => DropBehavior::Commit,
    2 => DropBehavior::Ignore,
    3 => DropBehavior::Panic,
    other => return Err(format!("invalid drop behavior byte {other}")),
};
Defensive patterns

Strategy: type-guard

Validate before calling

if raw > 3 {
    return Err(anyhow!("invalid DropBehavior byte {raw}"));
}
let behavior = DropBehavior::from(raw);

Type guard

pub fn is_valid_drop_behavior(raw: u8) -> bool {
    matches!(raw, 0 | 1 | 2 | 3)
}

Prevention

When it happens

Trigger: 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.

Common situations: Serialization format drift between binding versions; hand-written FFI glue mapping C ints to the enum; fuzzed input reaching the conversion.

Related errors


AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20). Data as JSON: /api/errors/93a8dc3813f51ecc. Report an issue: GitHub.