SeaQL/sea-orm · error
Failed to get tiny integer
Error message
Failed to get tiny integer
What it means
In `from_sqlx_mysql_row_to_proxy_row`, a column typed "TINYINT" (signed) is decoded with `row.try_get::<i8>` and `.expect("Failed to get tiny integer")`. The panic occurs when sqlx cannot decode the cell as i8 — typically a NULL requested as non-Option i8, or a type mismatch between the reported column type and the actual decoded value. Note MySQL reports TINYINT(1) as "TINYINT(1)", so a plain "TINYINT" branch sees other signed tinyint values.
Source
Thrown at sea-orm-sync/src/driver/sqlx_mysql.rs:409
"TINYINT UNSIGNED" => Value::TinyUnsigned(
row.try_get(c.ordinal())
.expect("Failed to get unsigned tiny integer"),
),
"SMALLINT UNSIGNED" => Value::SmallUnsigned(
row.try_get(c.ordinal())
.expect("Failed to get unsigned small integer"),
),
"INT UNSIGNED" => Value::Unsigned(
row.try_get(c.ordinal())
.expect("Failed to get unsigned integer"),
),
"MEDIUMINT UNSIGNED" | "BIGINT UNSIGNED" => Value::BigUnsigned(
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"))
}
View on GitHub (pinned to e29bcd1b41)
Solutions
- Make the column non-nullable or use COALESCE in the query.
- Decode as `Option<i8>` and map NULL to Value::TinyInt(None).
- Propagate the decode error as DbErr instead of panicking.
- Confirm the sqlx version in use matches sea-orm's pinned sqlx.
Example fix
// before
"TINYINT" => Value::TinyInt(
row.try_get(c.ordinal()).expect("Failed to get tiny integer"),
)
// after: tolerate NULL
"TINYINT" => Value::TinyInt(
row.try_get::<Option<i8>, _>(c.ordinal())
.expect("Failed to get tiny integer"),
) Defensive patterns
Strategy: validation
Validate before calling
// check NULL before decoding TINYINT as i8
if row.try_get_raw(c.ordinal())?.is_null() && c.type_info().name() == "TINYINT" {
// handle NULL path
} Try / catch
let v: Option<i8> = row.try_get(c.ordinal())?;
Prevention
- Declare signed tinyint columns NOT NULL when values are mandatory.
- Remember TINYINT(1) is routed to the boolean branch — check which branch your column hits.
- Cover proxy conversion with NULL fixtures.
- Pin sqlx to the version sea-orm was built with.
When it happens
Trigger: Proxy backend query against MySQL returning a signed TINYINT column that is NULL, or whose value fails i8 decoding (e.g. a boolean-ish or wider value under a mismatched type_info name).
Common situations: Nullable signed tinyint columns through the proxy backend; sqlx MySQL type_info naming differences across versions making the branch match the wrong value; computed columns reporting TINYINT while decoding differently.
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
- Failed to get boolean
- Failed to get unsigned tiny integer
- Failed to get unsigned small integer
- Failed to get unsigned integer
- Failed to get unsigned big integer
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/1036e2686ca2955d.
Report an issue: GitHub.