SeaQL/sea-orm · error
Failed to get year
Error message
Failed to get year
What it means
ProxyRow maps MySQL YEAR columns to a date Value and calls `row.try_get::<Option<chrono::NaiveDate>, _>()` with `expect("Failed to get year")`. This panics when sqlx cannot decode the YEAR column's value into `chrono::NaiveDate`. It indicates the raw value of a column reported as YEAR does not meet decode expectations (e.g. it arrives as an integer or string rather than a date).
Source
Thrown at sea-orm-sync/src/driver/sqlx_mysql.rs:498
),
#[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
- Change the column type from YEAR to SMALLINT or DATE in the schema; YEAR is rarely worth its compatibility pitfalls.
- Select with an explicit cast: `SELECT CAST(year_col AS DATE) FROM ...` or `CAST(year_col AS CHAR)` so the driver decodes a type it supports.
- Upgrade/downgrade sqlx to a version with correct MySQL YEAR decoding, or file/check upstream sqlx issues for YEAR support.
- Replace `.expect(...)` with error propagation in src/ (then run build-tools/make-sync.sh) so the failure becomes a `DbErr` instead of a panic.
Example fix
// before: SELECT year_col FROM t; -> panic in ProxyRow
// after: cast in SQL so sqlx sees a supported type
let stmt = Statement::from_string(
DatabaseBackend::MySql,
"SELECT CAST(year_col AS CHAR) AS year_col FROM t",
); Defensive patterns
Strategy: validation
Validate before calling
// Verify the column isn't MySQL YEAR before binding to NaiveDate decoding: -- SHOW COLUMNS FROM t LIKE 'year_col'; -- prefer SMALLINT/DATE over YEAR -- Or cast at query time: SELECT CAST(year_col AS CHAR) AS year_col FROM t;
Try / catch
// YEAR decode panics aren't DbErr; cast columns in SQL instead:
let stmt = Statement::from_string(
DatabaseBackend::MySql,
"SELECT CAST(year_col AS CHAR) AS year_col FROM t",
);
let rows = db.query_all(stmt)?; Prevention
- Avoid the MySQL YEAR type in new schemas; use SMALLINT or DATE.
- Always cast YEAR columns (CAST AS CHAR/DATE) when selecting them through SeaORM's proxy.
- Check sqlx release notes for MySQL YEAR decode support before upgrading.
- Test queries against MariaDB if you support it — YEAR encoding can differ.
When it happens
Trigger: A query against MySQL returns a YEAR column and sqlx fails to decode it as `chrono::NaiveDate` — commonly because the MySQL YEAR type is delivered over the wire as a 2-byte/integer value or short string ('2024') rather than a full date the NaiveDateTime/NaiveDate decoder accepts.
Common situations: Tables using MySQL's YEAR type (rare but real in legacy schemas); sqlx versions where YEAR decoding to NaiveDate is unsupported or broken; MariaDB returning YEAR with different wire encoding.
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/24ce227e62334de7.
Report an issue: GitHub.