{"record":{"id":"cddfbbe06412ea82","repo":"SeaQL/sea-orm","slug":"failed-to-get-boolean-cddfbb","errorCode":null,"errorMessage":"Failed to get boolean","messagePattern":"Failed to get boolean","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/driver/sqlx_mysql.rs","lineNumber":397,"sourceCode":"    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_mysql_row_to_proxy_row(row: &sqlx::mysql::MySqlRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-mysql/0.7.2/src/sqlx_mysql/protocol/text/column.rs.html\n    // https://docs.rs/sqlx-mysql/0.7.2/sqlx_mysql/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"TINYINT(1)\" | \"BOOLEAN\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n                        \"TINYINT UNSIGNED\" => Value::TinyUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned tiny integer\"),\n                        ),\n                        \"SMALLINT UNSIGNED\" => Value::SmallUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned small integer\"),\n                        ),\n                        \"INT UNSIGNED\" => Value::Unsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned integer\"),\n                        ),\n                        \"MEDIUMINT UNSIGNED\" | \"BIGINT UNSIGNED\" => Value::BigUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned big integer\"),\n                        ),\n                        \"TINYINT\" => Value::TinyInt(","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/src/driver/sqlx_mysql.rs#L379-L415","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Make the column NOT NULL or use a nullable-aware decode (Option<bool>) instead of try_get::<bool>.","Coalesce NULLs in SQL: SELECT IFNULL(flag, 0) AS flag.","Match the declared type-info string exactly with what your sqlx version reports for the column.","Replace expect with a mapped DbErr (QueryAssert/TypeNotFound) instead of panicking."],"exampleFix":"// before\n\"TINYINT(1)\" | \"BOOLEAN\" => Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\")),\n// after\n\"TINYINT(1)\" | \"BOOLEAN\" => Value::Bool(row.try_get::<Option<bool>, _>(c.ordinal())\n    .map_err(|e| DbErr::Query(RuntimeErr::Protocol(e.to_string())))?\n    .unwrap_or(false)),","handlingStrategy":"validation","validationCode":"-- Ensure boolean columns are NOT NULL or defaulted before decoding through the proxy:\nALTER TABLE users MODIFY is_active BOOLEAN NOT NULL DEFAULT FALSE;","typeGuard":"// Validate column metadata before decoding:\nfn is_non_null_bool(col: &Column) -> bool {\n    matches!(col.type_info().name(), \"TINYINT(1)\" | \"BOOLEAN\") && !col.nullable()\n}","tryCatchPattern":"// Panics are not catchable per-column; wrap whole row conversion:\nlet row = std::panic::catch_unwind(AssertUnwindSafe(|| ProxyRow::from_mysql_row(row, cols)))\n    .map_err(|_| DbErr::RecordNotFound(\"type mismatch decoding boolean\"))?;","preventionTips":["Keep boolean columns NOT NULL with a default","Use IFNULL in queries selecting nullable booleans","Check type_info().name() strings against your pinned sqlx version","Pin sqlx versions and review its MySQL type-naming changelog on upgrade"],"tags":["panic","mysql","type-decoding","sqlx"],"backgroundTag":"type-mismatch","analyzedSha":"e29bcd1b417c41a553b386fe94511d7c64a1c8ec","analyzedAt":"2026-09-10T11:31:52.468Z","contentChangedAt":"2026-09-10T11:31:52.468Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}