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.

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.

Appendix: 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)