SeaQL/sea-orm · error

Failed to get decimal

Error message

Failed to get decimal

What it means

This panic is raised by `.expect("Failed to get decimal")` in the sqlx MySQL driver's ProxyRow conversion when a column typed DECIMAL is decoded into `Option<bigdecimal::BigDecimal>` (behind the `with-bigdecimal` feature). If sqlx cannot decode the column value as a BigDecimal (e.g. the value's actual runtime type differs from what the type_info suggested, or the column holds a value BigDecimal cannot parse), the expect panics. It means the fetched DECIMAL value could not be materialized into the configured decimal crate type.

Source

Thrown at src/driver/sqlx_mysql.rs:525

                                .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. Make sure only one decimal feature (`with-bigdecimal` or `with-rust_decimal`) is enabled consistently across sea-orm, sea-orm-cli, and your code, so generated entity types match the runtime decode path.
  2. Align bigdecimal crate versions between sea-orm and sqlx in Cargo.lock (`cargo update -p bigdecimal --precise <compatible-version>`).
  3. Cast the column in SQL: `CAST(col AS CHAR)` and parse manually if the value has exotic scale/precision.
  4. Verify entity column types use Decimal and match the schema; regenerate entities with sea-orm-cli using the same feature flags.
  5. If precision/scale overflows, increase the decimal scale in the entity definition or round in SQL (`ROUND(col, n)`).

Example fix

// Cargo.toml before (mixed features)
sea-orm = { version = "1", features = ["sqlx-mysql", "with-bigdecimal", "with-rust_decimal"] }

// after (single decimal feature)
sea-orm = { version = "1", features = ["sqlx-mysql", "with-rust_decimal"] }
Defensive patterns

Strategy: validation

Validate before calling

// Verify schema precision fits the configured decimal type:
let res = db.query_all(Statement::from_string(
    DatabaseBackend::MySql,
    "SELECT COLUMN_NAME, NUMERIC_PRECISION, NUMERIC_SCALE FROM information_schema.COLUMNS
     WHERE TABLE_NAME = 'orders' AND DATA_TYPE = 'decimal'
       AND NUMERIC_PRECISION > 28",
)).await?;
if !res.is_empty() {
    // cast these columns in SQL (CAST(col AS DECIMAL(28,8))) or switch to with-bigdecimal
}

Prevention

When it happens

Trigger: Querying a MySQL DECIMAL (or NUMERIC) column while sea-orm is built with `with-bigdecimal`, and `row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())` returns a sqlx decode error -- typically a type mismatch between the wire value and BigDecimal.

Common situations: Mixed sqlx/sea-orm feature sets where bigdecimal versions diverge between dependencies; DECIMAL columns with unusual precision that overflow the configured scale; selecting DECIMAL via raw SQL proxy queries; switching from rust_decimal to bigdecimal (or vice versa) so the runtime value no longer matches the expected type.

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