SeaQL/sea-orm · error
Failed to get boolean
Error message
Failed to get boolean
What it means
Panic in sea-orm-sync's SQLite driver when a column whose type_info name is "BOOLEAN" cannot be decoded into the expected boolean type while constructing a ProxyRow. SQLite stores booleans as integers, so this fires when sqlx reports BOOLEAN but the underlying value is not a valid 0/1 integer (or is NULL where a non-Option bool is expected).
Source
Thrown at sea-orm-sync/src/driver/sqlx_sqlite.rs:415
}
}
#[cfg(feature = "proxy")]
pub(crate) fn from_sqlx_sqlite_row_to_proxy_row(row: &sqlx::sqlite::SqliteRow) -> crate::ProxyRow {
// https://docs.rs/sqlx-sqlite/0.7.2/src/sqlx_sqlite/type_info.rs.html
// https://docs.rs/sqlx-sqlite/0.7.2/sqlx_sqlite/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() {
"BOOLEAN" => {
Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean"))
}
"INTEGER" => {
Value::Int(row.try_get(c.ordinal()).expect("Failed to get integer"))
}
"BIGINT" | "INT8" => Value::BigInt(
row.try_get(c.ordinal()).expect("Failed to get big integer"),
),
"REAL" => {
Value::Double(row.try_get(c.ordinal()).expect("Failed to get double"))
}
"TEXT" => Value::String(
row.try_get::<Option<String>, _>(c.ordinal())
.expect("Failed to get string")
.map(Box::new),View on GitHub (pinned to e29bcd1b41)
Solutions
- Sanitize stored values so booleans are exactly 0 or 1 integers (UPDATE col SET col = CASE ... )
- Make the column NOT NULL with a DEFAULT 0 to eliminate NULL decodes
- Check with SELECT typeof(col), col to find offending values before re-querying via ProxyRow
- Replace .expect with error propagation and fall back to Value::Int for non-boolean values
Example fix
// before
"BOOLEAN" => {
Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean"))
}
// after
"BOOLEAN" => {
Value::Bool(row.try_get::<Option<bool>, _>(c.ordinal())
.expect("Failed to get boolean")
.unwrap_or(false))
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure SQLite boolean columns hold only 0/1 integers: // SELECT typeof(col), col FROM t WHERE col NOT IN (0, 1) OR col IS NULL;
Type guard
fn is_valid_bool_storage(v: Option<i64>) -> bool { matches!(v, Some(0) | Some(1)) } Try / catch
let row = std::panic::catch_unwind(|| proxy_query(db)).unwrap_or_else(|_| fallback_row());
Prevention
- Store booleans strictly as 0/1 integers
- Add NOT NULL DEFAULT 0 to boolean columns
- Never insert 'true'/'false' strings via raw SQL
- Audit legacy rows with typeof() before reading via ProxyRow
When it happens
Trigger: Reading a SQLite BOOLEAN-declared column whose stored value is NULL (try_get into non-Option bool), or whose stored value is something other than 0/1 (e.g. text 'true' or integer 2).
Common situations: Booleans inserted by another tool as strings 'true'/'false'; columns declared BOOLEAN but populated with arbitrary integers; NULL values in a NOT-NULL-assumed boolean column during migration from other databases.
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
- Failed to get integer
- Failed to get big integer
- Failed to get double
- Failed to get string
- Failed to get bytes
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/04e212e75377a1c9.
Report an issue: GitHub.