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

  1. 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.
  2. Cast suspect expressions to DATE in SQL (CAST(x AS DATE)) so the wire value matches the declared type.
  3. Verify the column's declared type in information_schema matches what the query returns (views/UNIONs can change the effective type).
  4. If you need dates beyond chrono's range, change the column to store YEAR/INT or select as string and parse manually.
  5. 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

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.