SeaQL/sea-orm · error
Failed to get unsigned tiny integer
Error message
Failed to get unsigned tiny integer
What it means
In `from_sqlx_mysql_row_to_proxy_row`, a column typed "TINYINT UNSIGNED" is decoded with `row.try_get::<u8>` and `.expect("Failed to get unsigned tiny integer")`. The panic fires when sqlx cannot decode the cell as u8 — typically a NULL value requested as a non-Option type, or a decode/type mismatch. This runs under the `proxy` feature when converting MySqlRows to ProxyRow.
Source
Thrown at sea-orm-sync/src/driver/sqlx_mysql.rs:393
pub(crate) fn from_sqlx_mysql_row_to_proxy_row(row: &sqlx::mysql::MySqlRow) -> crate::ProxyRow {
// https://docs.rs/sqlx-mysql/0.7.2/src/sqlx_mysql/protocol/text/column.rs.html
// https://docs.rs/sqlx-mysql/0.7.2/sqlx_mysql/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() {
"TINYINT(1)" | "BOOLEAN" => {
Value::Bool(row.try_get(c.ordinal()).expect("Failed to get boolean"))
}
"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(View on GitHub (pinned to e29bcd1b41)
Solutions
- Make the column non-nullable or use COALESCE(col, 0) in the query.
- Decode as `Option<u8>` and produce Value::TinyUnsigned(None) for NULLs.
- Replace .expect with proper error propagation so the failing column is reported.
- Align the sqlx version used at runtime with the one sea-orm was built against.
Example fix
// before
"TINYINT UNSIGNED" => Value::TinyUnsigned(
row.try_get(c.ordinal()).expect("Failed to get unsigned tiny integer"),
)
// after: tolerate NULL
"TINYINT UNSIGNED" => Value::TinyUnsigned(
row.try_get::<Option<u8>, _>(c.ordinal())
.expect("Failed to get unsigned tiny integer"),
) Defensive patterns
Strategy: validation
Validate before calling
// check NULL before decoding TINYINT UNSIGNED as u8
if row.try_get_raw(c.ordinal())?.is_null() && c.type_info().name() == "TINYINT UNSIGNED" {
// handle NULL path
} Try / catch
let v: Option<u8> = row.try_get(c.ordinal())?;
Prevention
- Declare unsigned tinyint columns NOT NULL when a value is always expected.
- Exercise proxy conversions with NULL-bearing fixtures.
- Avoid SELECT expressions that change the effective column type.
- Pin sqlx to sea-orm's tested version.
When it happens
Trigger: Proxy backend query against MySQL returning a TINYINT UNSIGNED column that is NULL, or whose actual value cannot be decoded into u8 (e.g. column type reported differently than the returned value after an expression/alias).
Common situations: Nullable unsigned tinyint columns (e.g. `age TINYINT UNSIGNED NULL`) in proxy result rows; UNION or CAST expressions changing the reported type; mismatched sqlx runtime vs compile-time type mapping.
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 small integer
- Failed to get unsigned integer
- Failed to get unsigned big integer
- Failed to get tiny integer
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/b2e938cb071e0cac.
Report an issue: GitHub.