SeaQL/sea-orm · error

Failed to get boolean

Error message

Failed to get boolean

What it means

In the sqlx MySQL ProxyRow conversion, a column typed TINYINT(1)/BOOLEAN is read with row.try_get::<bool, _>(ordinal).expect("Failed to get boolean"). If the actual runtime value is not a bool (type-info mismatch, NULL, or driver type-name drift), try_get errors and the expect panics. This is a strict type-decoding assumption inside proxy/derive-based row conversion.

Source

Thrown at src/driver/sqlx_mysql.rs:397

    }
}

#[cfg(feature = "proxy")]
pub(crate) fn from_sqlx_mysql_row_to_proxy_row(row: &sqlx::mysql::MySqlRow) -> crate::ProxyRow {
    // https://docs.rs/sqlx-mysql/0.7.2/src/sqlx_mysql/protocol/text/column.rs.html
    // https://docs.rs/sqlx-mysql/0.7.2/sqlx_mysql/types/index.html
    use sea_query::Value;
    use sqlx::{Column, Row, TypeInfo};
    crate::ProxyRow {
        values: row
            .columns()
            .iter()
            .map(|c| {
                (
                    c.name().to_string(),
                    match c.type_info().name() {
                        "TINYINT(1)" | "BOOLEAN" => {
                            Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean"))
                        }
                        "TINYINT UNSIGNED" => Value::TinyUnsigned(
                            row.try_get(c.ordinal())
                                .expect("Failed to get unsigned tiny integer"),
                        ),
                        "SMALLINT UNSIGNED" => Value::SmallUnsigned(
                            row.try_get(c.ordinal())
                                .expect("Failed to get unsigned small integer"),
                        ),
                        "INT UNSIGNED" => Value::Unsigned(
                            row.try_get(c.ordinal())
                                .expect("Failed to get unsigned integer"),
                        ),
                        "MEDIUMINT UNSIGNED" | "BIGINT UNSIGNED" => Value::BigUnsigned(
                            row.try_get(c.ordinal())
                                .expect("Failed to get unsigned big integer"),
                        ),
                        "TINYINT" => Value::TinyInt(

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Make the column NOT NULL or use a nullable-aware decode (Option<bool>) instead of try_get::<bool>.
  2. Coalesce NULLs in SQL: SELECT IFNULL(flag, 0) AS flag.
  3. Match the declared type-info string exactly with what your sqlx version reports for the column.
  4. Replace expect with a mapped DbErr (QueryAssert/TypeNotFound) instead of panicking.

Example fix

// before
"TINYINT(1)" | "BOOLEAN" => Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean")),
// after
"TINYINT(1)" | "BOOLEAN" => Value::Bool(row.try_get::<Option<bool>, _>(c.ordinal())
    .map_err(|e| DbErr::Query(RuntimeErr::Protocol(e.to_string())))?
    .unwrap_or(false)),
Defensive patterns

Strategy: validation

Validate before calling

-- Ensure boolean columns are NOT NULL or defaulted before decoding through the proxy:
ALTER TABLE users MODIFY is_active BOOLEAN NOT NULL DEFAULT FALSE;

Type guard

// Validate column metadata before decoding:
fn is_non_null_bool(col: &Column) -> bool {
    matches!(col.type_info().name(), "TINYINT(1)" | "BOOLEAN") && !col.nullable()
}

Try / catch

// Panics are not catchable per-column; wrap whole row conversion:
let row = std::panic::catch_unwind(AssertUnwindSafe(|| ProxyRow::from_mysql_row(row, cols)))
    .map_err(|_| DbErr::RecordNotFound("type mismatch decoding boolean"))?;

Prevention

When it happens

Trigger: Executing a query whose BOOLEAN/TINYINT(1) column returns NULL, or where the decoded Rust type doesn't match what sqlx reports (e.g. using ProxyDatabase or custom row types, or newer sqlx MySQL type naming).

Common situations: Nullable boolean columns decoded via the proxy driver; sqlx version upgrades changing type_info().name() strings so the match arm fires for a column whose value decodes as a different type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10). Data as JSON: /api/errors/cddfbbe06412ea82. Report an issue: GitHub.