SeaQL/sea-orm · error

Failed to get double

Error message

Failed to get double

What it means

This panic is raised by an `.expect("Failed to get double")` in sea-orm's ProxyRow driver for PostgreSQL (src/driver/sqlx_postgres.rs:540). When a column's reported type is FLOAT8/DOUBLE PRECISION, the code calls `row.try_get::<Option<f64>>` on the underlying sqlx row, and panics if sqlx cannot decode the value into f64. Typical root causes are the column actually holding a different type (e.g. numeric/text/NaN) or an sqlx version mismatch in type decoding.

Source

Thrown at src/driver/sqlx_postgres.rs:540

                        "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"))
                        }
                        #[cfg(feature = "postgres-array")]
                        "FLOAT8[]" | "DOUBLE PRECISION[]" => Value::Array(
                            sea_query::ArrayType::Double,
                            row.try_get::<Option<Vec<f64>>, _>(c.ordinal())
                                .expect("Failed to get double array")
                                .map(|vals| {
                                    Box::new(
                                        vals.into_iter()
                                            .map(|val| Value::Double(Some(val)))
                                            .collect(),
                                    )
                                }),
                        ),

                        "VARCHAR" | "CHAR" | "TEXT" | "NAME" => Value::String(
                            row.try_get::<Option<String>, _>(c.ordinal())
                                .expect("Failed to get string"),

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Check the actual column type with `\d table` or information_schema and confirm it is really float8/double precision; fix the schema or cast in SQL (`SELECT col::float8`).
  2. Align sea-orm and sqlx versions (same minor line) and rebuild so the type decoding matches; sqlx decode behavior for float8 has changed across versions.
  3. Enable sqlx logging (RUST_LOG=sqlx=debug) and reproduce to see the underlying sqlx decode error message identifying the column and expected/received types.
  4. If the value can legitimately be NaN/Infinity, cast to text or numeric in the query and read it via a supported type instead of f64.
  5. As a last resort, patch the expect to map the error and report the column name instead of panicking.

Example fix

// before
"FLOAT8" | "DOUBLE PRECISION" => Value::Double(
    row.try_get(c.ordinal()).expect("Failed to get double"),
)
// after (query-side cast so sqlx sees a real float8)
let value: Option<f64> = row.try_get(c.ordinal())
    .map_err(|e| DbErr::Custom(format!("float8 decode failed at col {}: {e}", c.ordinal())))?;
Defensive patterns

Strategy: validation

Validate before calling

// Before reading, verify the column really is float8 in Postgres:
// SELECT data_type FROM information_schema.columns
//   WHERE table_name=$1 AND column_name=$2;  -- expect 'double precision'
// Or cast defensively in the query: SELECT col::float8 FROM ...

Type guard

fn is_float8_col(c: &ProxyColumn) -> bool {
    matches!(c.ty.as_str(), "FLOAT8" | "DOUBLE PRECISION")
}

Try / catch

// expect() panics, so guard the process instead:
std::panic::catch_unwind(|| row_proxy_query(db, sql))
    .map_err(|p| DbErr::Custom(format!("decode panic: {p:?}")))?;

Prevention

When it happens

Trigger: Selecting a float8/double precision column whose actual wire value cannot decode to f64: e.g. the column was ALTERed to another type but the cached type name still says FLOAT8, a NaN/Infinity value with an sqlx version that rejects it into Option<f64>, or a view/expression whose result type differs from the declared FLOAT8.

Common situations: Schema drift after migrations (type renamed but query results re-decoded), using raw SQL views that return text or numeric under a float8 alias, mismatched sea-orm/sqlx versions where decoding behavior changed, or a proxy driver (sea-orm-proxy / sharding) reading a foreign table with incompatible type mapping.

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