SeaQL/sea-orm · error

Failed to get float

Error message

Failed to get float

What it means

This panic comes from an `.expect("Failed to get float")` inside `ProxyRow`, where SeaORM decodes a Postgres column typed FLOAT4/REAL via sqlx `row.try_get::<f32>`. It fires when sqlx cannot decode the raw value into the expected `Option<f32>` shape -- most often because the actual column type at runtime does not match the declared type the driver matched on, so the wire-format type OID differs from what sqlx expects. SeaORM uses `expect` rather than `Result` here, so the failure aborts the whole query instead of returning an error.

Source

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

                        "BIGINT" | "BIGSERIAL" | "INT8" => Value::BigInt(
                            row.try_get(c.ordinal()).expect("Failed to get big integer"),
                        ),
                        #[cfg(feature = "postgres-array")]
                        "BIGINT[]" | "BIGSERIAL[]" | "INT8[]" => Value::Array(
                            sea_query::ArrayType::BigInt,
                            row.try_get::<Option<Vec<i64>>, _>(c.ordinal())
                                .expect("Failed to get big integer array")
                                .map(|vals: Vec<i64>| {
                                    Box::new(
                                        vals.into_iter()
                                            .map(|val| Value::BigInt(Some(val)))
                                            .collect(),
                                    )
                                }),
                        ),

                        "FLOAT4" | "REAL" => {
                            Value::Float(row.try_get(c.ordinal()).expect("Failed to get float"))
                        }
                        #[cfg(feature = "postgres-array")]
                        "FLOAT4[]" | "REAL[]" => Value::Array(
                            sea_query::ArrayType::Float,
                            row.try_get::<Option<Vec<f32>>, _>(c.ordinal())
                                .expect("Failed to get float array")
                                .map(|vals| {
                                    Box::new(
                                        vals.into_iter()
                                            .map(|val| Value::Float(Some(val)))
                                            .collect(),
                                    )
                                }),
                        ),

                        "FLOAT8" | "DOUBLE PRECISION" => {
                            Value::Double(row.try_get(c.ordinal()).expect("Failed to get double"))
                        }

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Verify the actual column type in Postgres (`\d table` or information_schema.columns) matches REAL/FLOAT4; ALTER the column or update the entity to a compatible type and re-run.
  2. Ensure the SeaORM and sqlx Postgres versions are aligned and regenerated (`cargo update` together) so type OIDs match.
  3. Cast explicitly in raw queries: `SELECT mycol::REAL AS mycol` so the returned type matches the expected f32 decode.
  4. If the column can be NULL-typed or is a domain type, change the model to a type SeaORM maps natively (e.g. Double) or store as TEXT and parse manually.

Example fix

// before: entity expects REAL but DB column is DOUBLE PRECISION
pub price: f32,

// after: align entity type with actual column type
pub price: f64,
Defensive patterns

Strategy: validation

Validate before calling

// Verify the column type before querying
let row: (String,) = sqlx::query_as(
    "SELECT data_type FROM information_schema.columns WHERE table_name = $1 AND column_name = $2"
).bind("my_table").bind("price").fetch_one(&db).await?;
assert!(matches!(row.0.as_str(), "real"), "price must be REAL/FLOAT4, got {}", row.0);

Type guard

fn as_f32(v: &sea_orm::Value) -> Option<f32> {
    match v {
        sea_orm::Value::Float(x) => *x,
        _ => None,
    }
}

Prevention

When it happens

Trigger: Calling any SeaORM query (find/load/raw) whose result set includes a Postgres REAL/FLOAT4 column whose underlying value cannot be decoded as f32; typically after the column's actual type was altered (e.g. to DOUBLE PRECISION or NUMERIC) while the schema cache still reports REAL, or a custom domain/cast type reports type name REAL but has a different OID.

Common situations: Schema drift: `ALTER TABLE ... ALTER COLUMN ... TYPE DOUBLE PRECISION` run against a deployed DB while entity definitions still say REAL. Using Postgres extensions or domains over float types that sqlx cannot decode directly. Reading via a view whose column type differs from the entity. Mismatched SeaORM/sqlx minor versions with changed type-OID handling.

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