SeaQL/sea-orm · critical

Failed to get numeric array

Error message

Failed to get numeric array

What it means

This panic is raised inside sea-orm's Postgres row decoding when a NUMERIC[] (bigdecimal path) column cannot be converted to Option<Vec<bigdecimal::BigDecimal>>. sea-orm maps column types by their Postgres type name; `try_get` fails when sqlx's decoder cannot produce the requested Rust type (type mismatch, unexpected NULL representation, or a corrupted/unknown wire type). Because the code calls `.expect`, the underlying try_get error surfaces as a panic rather than a Result, aborting the thread doing the query.

Source

Thrown at sea-orm-sync/src/driver/sqlx_postgres.rs:596

                        #[cfg(feature = "with-bigdecimal")]
                        "NUMERIC" => Value::BigDecimal(
                            row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())
                                .expect("Failed to get numeric"),
                        ),
                        #[cfg(all(
                            feature = "with-rust_decimal",
                            not(feature = "with-bigdecimal")
                        ))]
                        "NUMERIC" => {
                            Value::Decimal(row.try_get(c.ordinal()).expect("Failed to get numeric"))
                        }

                        #[cfg(all(feature = "with-bigdecimal", feature = "postgres-array"))]
                        "NUMERIC[]" => Value::Array(
                            sea_query::ArrayType::BigDecimal,
                            row.try_get::<Option<Vec<bigdecimal::BigDecimal>>, _>(c.ordinal())
                                .expect("Failed to get numeric array")
                                .map(|vals| {
                                    Box::new(
                                        vals.into_iter()
                                            .map(|val| Value::BigDecimal(Some(val)))
                                            .collect(),
                                    )
                                }),
                        ),
                        #[cfg(all(
                            feature = "with-rust_decimal",
                            not(feature = "with-bigdecimal"),
                            feature = "postgres-array"
                        ))]
                        "NUMERIC[]" => Value::Array(
                            sea_query::ArrayType::Decimal,
                            row.try_get::<Option<Vec<rust_decimal::Decimal>>, _>(c.ordinal())
                                .expect("Failed to get numeric array")
                                .map(|vals| {

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Verify the actual Postgres type of the column with `\d table` or `SELECT pg_typeof(col)` and make sure it truly is `numeric[]`.
  2. Enable the matching cargo features (`with-bigdecimal`, `postgres-array`) and keep sea-orm / sea-query / sqlx versions aligned in Cargo.lock (`cargo update -p` to a compatible set).
  3. Cast the column in your SQL (`SELECT col::text[]` or `col::numeric[]`) so the returned type matches the decoder.
  4. If values include NaN/Infinity, sanitize them in SQL (`NULLIF`) or decode as text and parse manually.

Example fix

// before
SELECT tags FROM stats; -- tags is actually text[], expected numeric[]

// after
SELECT tags::numeric[] AS tags FROM stats;
Defensive patterns

Strategy: validation

Validate before calling

// Before running the query, verify column types:
let types: Vec<String> = db.query_all(Statement::from_string(
    DatabaseBackend::Postgres,
    "SELECT format_type(a.atttypid, a.atttypmod) FROM pg_attribute a WHERE a.attrelid = 'my_table'::regclass AND a.attname = 'col'",
)).await?;
assert_eq!(types[0].try_get::<_, String>(0)?, "numeric[]");

Try / catch

// These panics use .expect, so they cannot be caught as Results.
// Catch at the task boundary if you must keep running:
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(||
    entity::Entity::find().all(db)
));
match result {
    Ok(rows) => { /* use rows */ }
    Err(_) => { /* log and fall back to a text-cast query */ }
}

Prevention

When it happens

Trigger: Executing a raw query or find() that selects a `NUMERIC[]` column while the `with-bigdecimal` and `postgres-array` features are enabled, when sqlx cannot decode the cell into Option<Vec<BigDecimal>>: e.g. the actual column type is not really NUMERIC[] (view/reporting column returning text or record), or a sqlx/pgtypes version mismatch means the BigDecimal decoder rejects the wire format (e.g. unusual scale/precision or NaN encoding).

Common situations: Selecting numeric[] columns via raw SQL in `Statement::from_string` queries where the declared type differs from the returned type; mixing sea-orm and sqlx minor versions with incompatible bigdecimal decoding; values like 'NaN' or 'Infinity' stored in numeric arrays that the decoder refuses; querying generated columns or views where the type OID doesn't match NUMERICARRAY.

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