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`'s column-to-`Value` conversion in the MySQL driver. It means `sqlx::Row::try_get` failed while decoding a FLOAT column at the column's ordinal position into an `Option<f32>`. The library uses `expect` because conversion failures are considered unrecoverable during row proxying, so instead of returning a `Result` it panics with this message. Typically the column's declared type does not match the value actually stored (e.g. NULL handling or a schema drift where the column is not really a float).

Source

Thrown at sea-orm-sync/src/driver/sqlx_mysql.rs:422

                            row.try_get(c.ordinal())
                                .expect("Failed to get unsigned big integer"),
                        ),
                        "TINYINT" => Value::TinyInt(
                            row.try_get(c.ordinal())
                                .expect("Failed to get tiny integer"),
                        ),
                        "SMALLINT" => Value::SmallInt(
                            row.try_get(c.ordinal())
                                .expect("Failed to get small integer"),
                        ),
                        "INT" => {
                            Value::Int(row.try_get(c.ordinal()).expect("Failed to get integer"))
                        }
                        "MEDIUMINT" | "BIGINT" => Value::BigInt(
                            row.try_get(c.ordinal()).expect("Failed to get big integer"),
                        ),
                        "FLOAT" => {
                            Value::Float(row.try_get(c.ordinal()).expect("Failed to get float"))
                        }
                        "DOUBLE" => {
                            Value::Double(row.try_get(c.ordinal()).expect("Failed to get double"))
                        }

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

                        "CHAR" | "VARCHAR" | "TINYTEXT" | "TEXT" | "MEDIUMTEXT" | "LONGTEXT" => {
                            Value::String(
                                row.try_get::<Option<String>, _>(c.ordinal())
                                    .expect("Failed to get string")
                                    .map(Box::new),
                            )

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Verify the live table schema (`SHOW CREATE TABLE`) matches the metadata used to build ProxyRow; refresh metadata if the column type changed.
  2. Check that the column is actually MySQL FLOAT and not DECIMAL/DOUBLE or a string; adjust the schema or the query.
  3. Confirm NULL values are acceptable — try_get decodes `Option<f32>`, so a type mismatch (not NULL) is the usual culprit.
  4. Upgrade/align `sqlx` MySQL versions so FLOAT decoding behaves as expected, or patch the driver to fall back instead of panicking.

Example fix

// before
"FLOAT" => {
    Value::Float(row.try_get(c.ordinal()).expect("Failed to get float"))
}
// after
"FLOAT" => {
    Value::Float(row.try_get::<Option<f32>, _>(c.ordinal())
        .map_err(|e| DbErr::TryGetErr(...))? // propagate instead of panicking
        .unwrap_or_default())
}
Defensive patterns

Strategy: validation

Validate before calling

// Before querying, verify the column type matches expectations
let schema_matches = table_columns.iter().any(|c| c.name == "my_col" && c.type_name == "FLOAT");
if !schema_matches {
    // refresh metadata or fail fast instead of triggering the driver panic
}

Try / catch

// The library panics (expect), so standard try/catch does not apply.
// Catch the unwind boundary if using this in a service:
let result = std::panic::catch_unwind(|| proxy_row_from(&row, &columns));
match result {
    Ok(v) => v,
    Err(_) => return Err(DbErr::Custom("FLOAT column decode failed".into())),
}

Prevention

When it happens

Trigger: Querying a MySQL table where a column's declared type string is "FLOAT" but the raw value at `c.ordinal()` cannot be decoded as `Option<f32>` — e.g. schema altered after metadata was captured, incompatible column encoding, or out-of-range/stale column ordinals.

Common situations: Schema drift between the captured table metadata and the live database; using this driver against views or computed columns whose reported type string is FLOAT but whose returned values are not f32-decodable; mismatched driver/connector versions decoding MySQL FLOAT.

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