SeaQL/sea-orm · error

Failed to get integer

Error message

Failed to get integer

What it means

Panic when sea-orm-sync's SQLite driver cannot decode a column reported as "INTEGER" into an i32 while building a ProxyRow. SQLite integers are 64-bit, so this commonly fires when the stored value exceeds i32 range or is NULL where a non-Option i32 is expected.

Source

Thrown at sea-orm-sync/src/driver/sqlx_sqlite.rs:419

pub(crate) fn from_sqlx_sqlite_row_to_proxy_row(row: &sqlx::sqlite::SqliteRow) -> crate::ProxyRow {
    // https://docs.rs/sqlx-sqlite/0.7.2/src/sqlx_sqlite/type_info.rs.html
    // https://docs.rs/sqlx-sqlite/0.7.2/sqlx_sqlite/types/index.html
    use sea_query::Value;
    use sqlx::{Column, Row, TypeInfo};
    crate::ProxyRow {
        values: row
            .columns()
            .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())

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Change the column mapping so INTEGER values decode as i64 (BigInt) instead of i32, or widen the entity field to i64
  2. Fix out-of-range rows (SELECT * FROM t WHERE col > 2147483647 OR col < -2147483648)
  3. Add NOT NULL DEFAULT constraints to avoid NULL decode failures
  4. Propagate the sqlx error instead of .expect so callers can handle per-row failures

Example fix

// before
"INTEGER" => {
    Value::Int(row.try_get(c.ordinal()).expect("Failed to get integer"))
}
// after
"INTEGER" => match row.try_get::<i64, _>(c.ordinal()) {
    Ok(v) if v >= i32::MIN as i64 && v <= i32::MAX as i64 => Value::Int(v as i32),
    Ok(v) => Value::BigInt(v),
    Err(e) => panic!("Failed to get integer for col {}: {}", c.name(), e),
}
Defensive patterns

Strategy: validation

Validate before calling

// Detect out-of-i32-range INTEGER values before decoding:
// SELECT * FROM t WHERE col > 2147483647 OR col < -2147483648 OR col IS NULL;

Type guard

fn fits_i32(v: i64) -> bool { v >= i32::MIN as i64 && v <= i32::MAX as i64 }

Try / catch

let row = std::panic::catch_unwind(|| proxy_query(db)).unwrap_or_else(|_| fallback_row());

Prevention

When it happens

Trigger: Reading an INTEGER column whose value is > i32::MAX or < i32::MIN (try_get::<i32> fails with a range error), or a NULL value decoded into a non-Option type.

Common situations: SQLite tables created with 64-bit values (e.g. timestamps, snowflake IDs) read through a schema that maps INTEGER to i32; data imported from Postgres BIGINT columns; NULLs in legacy rows.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10). Data as JSON: /api/errors/7433a181703ea3e7. Report an issue: GitHub.