SeaQL/sea-orm · error

Failed to get unsigned tiny integer

Error message

Failed to get unsigned tiny integer

What it means

For MySQL columns named 'TINYINT UNSIGNED', the proxy row decoder calls row.try_get(c.ordinal()).expect("Failed to get unsigned tiny integer"), assuming the value decodes as u8. A NULL value, or a mismatch between the reported type-info name and the actual stored Rust type, makes try_get fail and the expect panics.

Source

Thrown at src/driver/sqlx_mysql.rs:401

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

  1. Avoid NULLs on these columns (NOT NULL constraint) or decode as Option<u8> with a defined default.
  2. Use SQL COALESCE/IFNULL to substitute 0 for NULL unsigned values.
  3. Verify the type-info name strings against your sqlx version's MySQL type naming.
  4. Convert the try_get error into a DbErr instead of panicking with expect.

Example fix

// before
"TINYINT UNSIGNED" => Value::TinyUnsigned(
    row.try_get(c.ordinal()).expect("Failed to get unsigned tiny integer")),
// after
"TINYINT UNSIGNED" => Value::TinyUnsigned(
    row.try_get::<Option<u8>, _>(c.ordinal())
        .map_err(|e| DbErr::Query(RuntimeErr::Protocol(e.to_string())))?
        .unwrap_or(0)),
Defensive patterns

Strategy: validation

Validate before calling

-- Ensure unsigned tinyint columns cannot be NULL:
ALTER TABLE items MODIFY retry_count TINYINT UNSIGNED NOT NULL DEFAULT 0;

Type guard

fn decodable_u8(col: &Column) -> bool {
    col.type_info().name() == "TINYINT UNSIGNED" && !col.nullable()
}

Try / catch

let converted = std::panic::catch_unwind(AssertUnwindSafe(|| ProxyRow::from_mysql_row(row, cols)));
if converted.is_err() { return Err(DbErr::Query(RuntimeErr::Protocol("unsigned tinyint decode failed".into()))); }

Prevention

When it happens

Trigger: Selecting a nullable TINYINT UNSIGNED column through the sqlx MySQL proxy path; type_info().name() returns 'TINYINT UNSIGNED' but the underlying value cannot be decoded as u8 (NULL or driver representation change).

Common situations: Migrating sqlx versions where unsigned column representations changed; proxy/mock databases returning rows whose declared types don't match their payload types.

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/50eae7a2e0bdc1a7. Report an issue: GitHub.