SeaQL/sea-orm · error

Failed to get time

Error message

Failed to get time

What it means

This panic comes from the `with-chrono` TIME branch of `ProxyRow` in the MySQL driver: `sqlx::Row::try_get::<Option<chrono::NaiveTime>, _>` failed for a "TIME" column at `c.ordinal()`. The `expect` turns the sqlx decode error into a panic with "Failed to get time". It means the stored value cannot be decoded as a `chrono::NaiveTime`, typically because the column's live type differs from the captured metadata or the value is malformed.

Source

Thrown at sea-orm-sync/src/driver/sqlx_mysql.rs:472

                        ),

                        #[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. Check for MySQL TIME values exceeding chrono's range (e.g. '850:00:00') and normalize them.
  2. Refresh the captured table metadata so TIME mapping matches the live column type.
  3. Verify the column is genuinely TIME; correct the schema or the driver's type mapping if not.
  4. Patch the driver to propagate DbErr instead of panicking, revealing the underlying sqlx error.

Example fix

// before
"TIME" => Value::ChronoTime(
    row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())
        .expect("Failed to get time")
        .map(Box::new),
)
// after
"TIME" => Value::ChronoTime(
    row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())
        .map_err(|e| DbErr::TryGetErr(...))? // propagate instead of panicking
        .map(Box::new),
)
Defensive patterns

Strategy: validation

Validate before calling

// MySQL TIME can exceed 24h (e.g. '850:00:00') which chrono cannot decode; detect first:
// SELECT COUNT(*) FROM t WHERE time_col > '23:59:59'; must be 0 or handled
assert_eq!(col.type_name, "TIME");

Try / catch

// The driver panics via .expect; wrap the boundary:
std::panic::catch_unwind(|| proxy_row_from(&row, &columns))
    .map_err(|_| DbErr::Custom("TIME column decode failed".into()))?

Prevention

When it happens

Trigger: Reading a MySQL TIME column while compiled with `with-chrono`, when the raw value is not decodable as `chrono::NaiveTime` — e.g. the column was altered to VARCHAR/DATETIME, or contains invalid time strings.

Common situations: MySQL TIME values out of chrono's supported range (MySQL allows large hour values like '850:00:00'); stale metadata after ALTER TABLE; feature-flag mismatches between chrono and time.

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