SeaQL/sea-orm · error

Failed to get decimal

Error message

Failed to get decimal

What it means

This is a panic raised by `.expect("Failed to get decimal")` inside ProxyRow, which converts a sqlx MySQL row into SeaORM proxy values. When a column's type info says DECIMAL but `row.try_get::<Option<BigDecimal>>` fails (type mismatch between the declared column type and the actually decoded value, or an unexpected NULL/type encoding), the expect aborts the process with this message instead of returning an error.

Source

Thrown at sea-orm-sync/src/driver/sqlx_mysql.rs:517

                                .map(Box::new),
                        ),
                        #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
                        "YEAR" => Value::TimeDate(
                            row.try_get::<Option<time::Date>, _>(c.ordinal())
                                .expect("Failed to get year")
                                .map(Box::new),
                        ),

                        "ENUM" | "SET" | "GEOMETRY" => Value::String(
                            row.try_get::<Option<String>, _>(c.ordinal())
                                .expect("Failed to get serialized string")
                                .map(Box::new),
                        ),

                        #[cfg(feature = "with-bigdecimal")]
                        "DECIMAL" => Value::BigDecimal(
                            row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())
                                .expect("Failed to get decimal")
                                .map(Box::new),
                        ),
                        #[cfg(all(
                            feature = "with-rust_decimal",
                            not(feature = "with-bigdecimal")
                        ))]
                        "DECIMAL" => Value::Decimal(
                            row.try_get::<Option<rust_decimal::Decimal>, _>(c.ordinal())
                                .expect("Failed to get decimal")
                                .map(Box::new),
                        ),

                        #[cfg(feature = "with-json")]
                        "JSON" => Value::Json(
                            row.try_get::<Option<serde_json::Value>, _>(c.ordinal())
                                .expect("Failed to get json")
                                .map(Box::new),
                        ),

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Verify the column's actual MySQL type matches DECIMAL and its precision/scale is representable as BigDecimal; fix the schema or cast in SQL (CAST(col AS DECIMAL(m,d))).
  2. Enable/disable the right feature: with-bigdecimal vs with-rust_decimal must match the crate your Cargo.toml actually uses for decimals.
  3. Upgrade sea-orm and sqlx to matching, current versions so MySQL DECIMAL decoding is handled correctly.
  4. Replace or wrap the proxy row conversion so a decode failure surfaces as a Result error instead of a panic (patch ProxyRow to use ok_or + From).

Example fix

// before (panics)
row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())
    .expect("Failed to get decimal")
// after (returns error)
row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())
    .map_err(|e| DbErr::Custom(format!("failed to decode decimal column {}: {e}", c.name())))?
Defensive patterns

Strategy: validation

Validate before calling

// Before converting rows, confirm the column type is decodable as BigDecimal
let info = c.type_info().name();
if info != "DECIMAL" {
    return Err(format!("unexpected column type {info} for decimal decoding"));
}
// Optionally verify data: SELECT col IS NOT NULL, JSON/CAST checks in SQL

Type guard

fn is_decimal_column(c: &sqlx::mysql::MySqlColumn) -> bool {
    c.type_info().name() == "DECIMAL"
}

Prevention

When it happens

Trigger: Reading a MySQL DECIMAL/NUMERIC column with the with-bigdecimal feature enabled while sqlx decodes a value that cannot be represented as Option<BigDecimal> — e.g. the column type_info reports DECIMAL but the underlying value is a string, an out-of-range number, or the driver returns an incompatible wire type.

Common situations: Decoding DECIMAL columns with unusual precision/scale, MySQL driver/driver-version mismatches where DECIMAL is returned as String, schema drift where a column changed type after the metadata was cached, or proxy-row conversions run against exotic column types (e.g. DECIMAL UNSIGNED or NEWDECIMAL labeled differently).

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