SeaQL/sea-orm · error

Failed to get double

Error message

Failed to get double

What it means

Proxy-row conversion maps "REAL" columns with row.try_get::<f64>(ordinal) and unwraps with expect("Failed to get double"). It panics when the stored value is NULL or not decodable as f64. The branch is selected from the declared type info, so SQLite dynamic typing can still hand back a mismatched value.

Source

Thrown at src/driver/sqlx_sqlite.rs:436

            .iter()
            .map(|c| {
                (
                    c.name().to_string(),
                    match c.type_info().name() {
                        "BOOLEAN" => {
                            Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean"))
                        }

                        "INTEGER" => {
                            Value::Int(row.try_get(c.ordinal()).expect("Failed to get integer"))
                        }

                        "BIGINT" | "INT8" => Value::BigInt(
                            row.try_get(c.ordinal()).expect("Failed to get big integer"),
                        ),

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

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

                        "BLOB" => Value::Bytes(
                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())
                                .expect("Failed to get bytes")
                                .map(Box::new),
                        ),

                        #[cfg(feature = "with-chrono")]
                        "DATETIME" => {
                            use chrono::{DateTime, Utc};

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Coalesce NULLs: SELECT IFNULL(price, 0.0) AS price ...
  2. Declare float columns NOT NULL with a default
  3. Fix import tooling to write numeric types
  4. Use a non-proxy driver so failures become DbErr instead of panics

Example fix

// before
SELECT AVG(score) AS score FROM results; -- NULL on empty set
// after
SELECT IFNULL(AVG(score), 0.0) AS score FROM results;
Defensive patterns

Strategy: try-catch

Validate before calling

// Coalesce nullable floats in SQL before proxy conversion:
// SELECT IFNULL(score, 0.0) AS score FROM results;

Type guard

fn as_f64(v: &sea_query::Value) -> Option<f64> {
    match v { sea_query::Value::Double(d) => Some(*d), sea_query::Value::Float(f) => Some(*f as f64), _ => None }
}

Try / catch

let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| from_sqlx_sqlite_row_to_proxy_row(&row)));
if result.is_err() { /* fall back to manual decode with defaults */ }

Prevention

When it happens

Trigger: Querying a REAL/FLOAT/DOUBLE-declared column containing NULL or an integer/text value via the proxy driver.

Common situations: Float columns populated with NULL by partial inserts; text values written by import scripts; expressions like SUM over empty sets returning NULL.

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