SeaQL/sea-orm · error
Failed to get year
Error message
Failed to get year
What it means
ProxyRow panicked while converting a MySQL YEAR column with `with-chrono`: the driver attempted `row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())` and `.expect("Failed to get year")` panicked because sqlx returned a decode error — the YEAR wire value (often a u16/integer) is not decodable as NaiveDate by sqlx's MySQL decoder.
Source
Thrown at src/driver/sqlx_mysql.rs:506
),
#[cfg(feature = "with-chrono")]
"DATETIME" => Value::ChronoDateTime(
row.try_get::<Option<chrono::NaiveDateTime>, _>(c.ordinal())
.expect("Failed to get datetime")
.map(Box::new),
),
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"DATETIME" => Value::TimeDateTime(
row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())
.expect("Failed to get datetime")
.map(Box::new),
),
#[cfg(feature = "with-chrono")]
"YEAR" => Value::ChronoDate(
row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())
.expect("Failed to get year")
.map(Box::new),
),
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"YEAR" => Value::TimeDate(
row.try_get::<Option<time::Date>, _>(c.ordinal())
.expect("Failed to get year")
.map(Box::new),
),
"ENUM" | "SET" | "GEOMETRY" => Value::String(
row.try_get::<Option<String>, _>(c.ordinal())
.expect("Failed to get serialized string")
.map(Box::new),
),
#[cfg(feature = "with-bigdecimal")]
"DECIMAL" => Value::BigDecimal(
row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())View on GitHub (pinned to e29bcd1b41)
Solutions
- Avoid decoding YEAR as a date: cast in SQL — SELECT CAST(y AS CHAR) AS y or SELECT y + 0 AS y — and read it as a String/integer.
- Better: migrate the column type from YEAR to SMALLINT in the schema so it maps to an integer Value.
- Select the year wrapped as a DATE ( MAKEDATE(y, 1) ) only if you genuinely need a NaiveDate.
- Check the sea-orm/sqlx versions: newer sqlx versions handle YEAR differently; upgrade or downgrade in lockstep.
- If only the proxy/raw path breaks, prefer generated entity queries (typed Decodable) over ProxyRow for YEAR columns.
Example fix
// before — YEAR column decoded as NaiveDate, panics SELECT founded_year FROM companies // after — read YEAR as an integer SELECT founded_year + 0 AS founded_year FROM companies
Defensive patterns
Strategy: validation
Validate before calling
// Check the column type before treating YEAR as a date
let ty: String = db.query_one(&Statement::from_string(
"SELECT COLUMN_TYPE AS t FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'companies' AND COLUMN_NAME = 'founded_year'",
DbBackend::MySql)).await?.unwrap().try_get("t")?;
if ty.starts_with("year") { /* decode as i32/String, never NaiveDate */ } Type guard
fn is_year_column(col_type: &str) -> bool {
col_type.eq_ignore_ascii_case("year") || col_type.starts_with("year(")
} Try / catch
// Prefer avoiding the panic entirely by mapping YEAR to integers in SQL
let year: Option<i32> = row.try_get(ordinal) // via `founded_year + 0`
.map_err(|_| YearDecodeFallback)?; Prevention
- Treat MySQL YEAR as an integer, never a date, in raw/proxy queries
- Migrate YEAR columns to SMALLINT in the schema
- Cast YEAR to CHAR or y+0 in SELECT lists
- Prefer typed entity queries over ProxyRow for YEAR columns
- Verify sqlx version behavior for YEAR decoding after upgrades
When it happens
Trigger: Selecting a YEAR-typed column: the MySQL wire type for YEAR is an integer year, which frequently cannot be decoded into NaiveDate, especially when the value is fetched as numeric (YEAR columns read via binary protocol return u16). Any YEAR column read through ProxyRow with chrono enabled can hit this.
Common situations: Schemas using YEAR(4) columns; proxy/raw-SQL paths that bypass generated entity typing; version changes in sqlx changing how YEAR is delivered; mixing proxy decoding with typed column expectations.
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/4d6e2c44f71fbcb1.
Report an issue: GitHub.