SeaQL/sea-orm · error

Failed to get boolean array

Error message

Failed to get boolean array

What it means

This panic comes from `.expect("Failed to get boolean array")` in sea-orm's sqlx Postgres ProxyRow conversion for "BOOL[]" columns (behind the `postgres-array` feature), decoding into `Option<Vec<bool>>`. The outer Option handles SQL NULL, but a decode failure -- such as a multidimensional array, an array containing NULL elements where Vec<bool> cannot hold them, or a type mismatch -- makes try_get error and the expect panic.

Source

Thrown at src/driver/sqlx_postgres.rs:444

    // https://docs.rs/sqlx-postgres/0.7.2/sqlx_postgres/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() {
                        "BOOL" => {
                            Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean"))
                        }
                        #[cfg(feature = "postgres-array")]
                        "BOOL[]" => Value::Array(
                            sea_query::ArrayType::Bool,
                            row.try_get::<Option<Vec<bool>>, _>(c.ordinal())
                                .expect("Failed to get boolean array")
                                .map(|vals| {
                                    Box::new(
                                        vals.into_iter()
                                            .map(|val| Value::Bool(Some(val)))
                                            .collect(),
                                    )
                                }),
                        ),

                        "\"CHAR\"" => Value::TinyInt(
                            row.try_get(c.ordinal())
                                .expect("Failed to get small integer"),
                        ),
                        #[cfg(feature = "postgres-array")]
                        "\"CHAR\"[]" => Value::Array(
                            sea_query::ArrayType::TinyInt,
                            row.try_get::<Option<Vec<i8>>, _>(c.ordinal())
                                .expect("Failed to get small integer array")

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Ensure array elements are never NULL: `UPDATE t SET col = ARRAY_REMOVE(col, NULL)` or add NOT NULL constraints on elements at write time.
  2. Cast multidimensional arrays to 1-D in SQL or select with `unnest(col)` instead of the array directly.
  3. If NULL elements are legitimate, select as text (`col::text`) and parse manually into Vec<Option<bool>>.
  4. Verify the `postgres-array` feature is enabled consistently and entity types use Vec<bool> matching a true 1-D bool[] column.
  5. Align sqlx/sea-orm versions if array decoding behavior changed after an upgrade.

Example fix

// before (array with NULL elements panics)
"SELECT flags FROM items"  -- flags = '{t,null}'::bool[]

// after (strip NULLs at query time)
"SELECT ARRAY_REMOVE(flags, NULL) AS flags FROM items"
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the array is 1-D and contains no NULL elements before decoding as Vec<bool>:
let bad = db.query_all(Statement::from_string(
    DatabaseBackend::Postgres,
    "SELECT id FROM items
      WHERE flags IS NOT NULL
        AND (array_ndims(flags) <> 1 OR EXISTS (SELECT 1 FROM unnest(flags) v WHERE v IS NULL))",
)).await?;
assert!(bad.is_empty(), "flags must be a 1-D bool[] without NULL elements");

Try / catch

// Sanitize in SQL to keep the decode total:
// SELECT ARRAY_REMOVE(flags, NULL) AS flags FROM items
// Or parse from text for full control:
let raw: Option<String> = row.try_get("flags")?;
let flags: Vec<Option<bool>> = raw
    .map(|s| s.trim_matches(|c| c == '{' || c == '}')
        .split(',')
        .map(|x| match x.trim() { "t" | "true" => Some(true), "f" | "false" => Some(false), _ => None })
        .collect())
    .unwrap_or_default();

Prevention

When it happens

Trigger: Reading a Postgres BOOLEAN[] column where `row.try_get::<Option<Vec<bool>>, _>(c.ordinal())` fails: the column is a multidimensional array (bool[][]), contains NULL elements (NULL inside the array is not representable in Vec<bool>), or the runtime type differs from BOOL[].

Common situations: Arrays with NULL elements (`ARRAY[true,NULL]::bool[]`); dimensionality drift after schema changes; selecting bool[] via raw SQL proxy queries; enabling/disabling the postgres-array feature so decode expectations change; sqlx version upgrades altering array decoding.

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/b82fc5d2f70f7153. Report an issue: GitHub.