SeaQL/sea-orm · error
Failed to get date
Error message
Failed to get date
What it means
ProxyRow panicked while converting a MySQL DATE column under the `with-chrono` feature: `row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())` failed and `.expect("Failed to get date")` aborted. sqlx could not decode the raw value as chrono::NaiveDate, meaning the value does not match the declared DATE type.
Source
Thrown at src/driver/sqlx_mysql.rs:467
}
#[cfg(feature = "with-chrono")]
"TIMESTAMP" => Value::ChronoDateTimeUtc(
row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())
.expect("Failed to get timestamp")
.map(Box::new),
),
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"TIMESTAMP" => Value::TimeDateTime(
row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())
.expect("Failed to get timestamp")
.map(Box::new),
),
#[cfg(feature = "with-chrono")]
"DATE" => Value::ChronoDate(
row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())
.expect("Failed to get date")
.map(Box::new),
),
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"DATE" => Value::TimeDate(
row.try_get::<Option<time::Date>, _>(c.ordinal())
.expect("Failed to get date")
.map(Box::new),
),
#[cfg(feature = "with-chrono")]
"TIME" => Value::ChronoTime(
row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())
.expect("Failed to get time")
.map(Box::new),
),
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"TIME" => Value::TimeTime(
row.try_get::<Option<time::Time>, _>(c.ordinal())View on GitHub (pinned to e29bcd1b41)
Solutions
- Clean up zero/invalid dates: UPDATE t SET d = NULL WHERE d = '0000-00-00' and enable strict mode so MySQL rejects them going forward.
- Cast suspect expressions to DATE in SQL (CAST(x AS DATE)) so the wire value matches the declared type.
- Verify the column's declared type in information_schema matches what the query returns (views/UNIONs can change the effective type).
- If you need dates beyond chrono's range, change the column to store YEAR/INT or select as string and parse manually.
- Upgrade sea-orm/sqlx together if the failure started after a dependency bump — decode strictness changed across versions.
Example fix
// before SELECT birth_date FROM users -- row with '0000-00-00' panics // after SELECT NULLIF(birth_date, '0000-00-00') AS birth_date FROM users
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: count undecodable DATE values
// SELECT COUNT(*) FROM users WHERE birth_date = '0000-00-00'
let n = fetch_count(db, "users", "birth_date = '0000-00-00'").await?;
if n > 0 { eprintln!("fix {} zero dates before querying", n); } Type guard
fn valid_mysql_date(s: &str) -> bool {
s != "0000-00-00" && chrono::NaiveDate::parse_from_str(s, "%Y-%m-%d").is_ok()
} Try / catch
let decoded = std::panic::catch_unwind(|| proxy_row.decode_date(ordinal)).ok(); let date = decoded.flatten().or_else(|| fallback_parse_date_as_string(ordinal));
Prevention
- Run MySQL with strict mode; forbid zero dates
- NULLIF zero dates in raw SELECTs against legacy tables
- CAST expression results to DATE so declared and runtime types match
- Check views/UNION branches for effective-type drift
- Keep dates within chrono's representable range or change the column type
When it happens
Trigger: Fetching a DATE column whose value is the MySQL zero date '0000-00-00', an out-of-chrono-range date (year 0 or > ~year 262000), or a DATE-valued expression/string that sqlx refuses to coerce to NaiveDate.
Common situations: Databases imported from non-strict legacy systems containing '0000-00-00'; dates outside chrono's supported range; columns typed DATE in metadata but actually returned as VARCHAR by a view or UNION.
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/87591933c62ae758.
Report an issue: GitHub.