SeaQL/sea-orm · error

Failed to get bytes

Error message

Failed to get bytes

What it means

Panic when sea-orm-sync's SQLite driver cannot decode a "BLOB" column into Option<Vec<u8>> while building a ProxyRow. sqlx fails when the physical value under a BLOB-typed column is not actually a blob (TEXT/INTEGER/REAL storage class), since SQLite's typing is per-value, not per-column.

Source

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

                        }

                        "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())
                                .expect("Failed to get bytes")
                                .map(Box::new),
                        ),

                        #[cfg(feature = "with-chrono")]
                        "DATETIME" => {
                            use chrono::{DateTime, Utc};

                            Value::ChronoDateTimeUtc(
                                row.try_get::<Option<DateTime<Utc>>, _>(c.ordinal())
                                    .expect("Failed to get timestamp")
                                    .map(Box::new),
                            )
                        }
                        #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
                        "DATETIME" => {
                            use time::OffsetDateTime;
                            Value::TimeDateTimeWithTimeZone(
                                row.try_get::<Option<OffsetDateTime>, _>(c.ordinal())

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Check storage classes (SELECT typeof(col)) and convert: UPDATE t SET col = CAST(col AS BLOB) WHERE typeof(col) != 'blob'
  2. Insert binary data through typed entity models with Vec<u8> fields rather than raw SQL strings
  3. If values are legitimately text, fix the column type declaration or the match arm so TEXT columns decode as strings
  4. Propagate the sqlx error with column context instead of .expect

Example fix

// before
"BLOB" => Value::Bytes(
    row.try_get::<Option<Vec<u8>>, _>(c.ordinal())
        .expect("Failed to get bytes")
        .map(Box::new),
),
// after
"BLOB" => Value::Bytes(
    row.try_get::<Option<Vec<u8>>, _>(c.ordinal())
        .unwrap_or_else(|e| panic!("Failed to get bytes for col {}: {}", c.name(), e))
        .map(Box::new),
)
Defensive patterns

Strategy: validation

Validate before calling

// Verify BLOB columns hold blob storage class:
// SELECT typeof(col), count(*) FROM t GROUP BY typeof(col);

Type guard

fn is_blob_storage(type_of: &str) -> bool { type_of == "blob" }

Try / catch

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

Prevention

When it happens

Trigger: Reading a BLOB column whose stored value is text or numeric storage class, or any sqlx decode error on that column while the type_info reports "BLOB".

Common situations: Binary data inserted as hex/text strings by another tool; columns declared BLOB but storing serialized JSON as text; mixed storage after imports from other databases.

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