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
- Change the column mapping so INTEGER values decode as i64 (BigInt) instead of i32, or widen the entity field to i64
- Fix out-of-range rows (SELECT * FROM t WHERE col > 2147483647 OR col < -2147483648)
- Add NOT NULL DEFAULT constraints to avoid NULL decode failures
- 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
- Use i64/BigInt entity fields for SQLite INTEGER columns
- Migrate large values (ids, timestamps) out of i32-mapped columns
- Add NOT NULL DEFAULT constraints
- Check imported data for values beyond i32 range
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
- Failed to get boolean
- Failed to get big integer
- Failed to get double
- Failed to get string
- Failed to get bytes
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/7433a181703ea3e7.
Report an issue: GitHub.