SeaQL/sea-orm · error

Failed to get time

Error message

Failed to get time

What it means

ProxyRow panicked while converting a MySQL TIME column under `with-chrono`: `row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())` returned Err and `.expect("Failed to get time")` panicked. sqlx could not decode the value as chrono::NaiveTime, i.e. the wire value does not conform to the declared TIME type.

Source

Thrown at src/driver/sqlx_mysql.rs:480

                        ),

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

                        #[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())

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. If the column stores durations, don't decode it as TIME: select it as a string/seconds number (TIME_TO_SEC(col)) and convert in Rust, or change the column to BIGINT seconds.
  2. Clamp or validate values in SQL: SELECT LEAST(col, '23:59:59') when you know values should be times of day.
  3. Enable strict mode and add CHECK constraints so invalid time-of-day values cannot be inserted.
  4. Verify the effective type of expressions (TIMEDIFF, ADDTIME) and cast appropriately before fetching.
  5. Upgrade sqlx/sea-orm in lockstep if decode behavior changed after a dependency update.

Example fix

// before — duration column exceeds NaiveTime range, panics
SELECT elapsed_time FROM jobs

// after — fetch as seconds instead of TIME
SELECT TIME_TO_SEC(elapsed_time) AS elapsed_seconds FROM jobs
Defensive patterns

Strategy: validation

Validate before calling

// TIME columns used for durations exceed NaiveTime range; verify first
// SELECT COUNT(*) FROM jobs WHERE elapsed_time > '23:59:59'
if count_over_24h(db, "jobs", "elapsed_time").await? > 0 {
    bail!("column stores durations; decode as TIME_TO_SEC instead");
}

Type guard

fn is_time_of_day(s: &str) -> bool {
    chrono::NaiveTime::parse_from_str(s, "%H:%M:%S").is_ok()
}

Try / catch

let time_val = std::panic::catch_unwind(|| row.try_decode_time(ordinal)).ok();
match time_val {
    Some(v) => v,
    None => fetch_as_seconds(ordinal).await, // TIME_TO_SEC fallback
}

Prevention

When it happens

Trigger: Reading a TIME column holding an out-of-range value (MySQL TIME supports up to 838:59:59, far beyond NaiveTime's 24h), negative durations, or an expression that returns a string/packed value instead of a decodable TIME.

Common situations: Columns used to store durations or intervals rather than times of day — the top cause, since MySQL TIME legitimately holds values chrono::NaiveTime cannot represent; TIMEDIFF() results; legacy data with negative times.

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