SeaQL/sea-orm · error
Failed to get timestamp
Error message
Failed to get timestamp
What it means
Panic when sea-orm-sync's SQLite driver (with-chrono feature) cannot decode a "DATETIME" column into Option<chrono::DateTime<Utc>> while building a ProxyRow. sqlx requires specific string formats (RFC3339 with offset) for DateTime<Utc>, so any DATETIME value stored in a different format — or NULL handled incorrectly — triggers this panic.
Source
Thrown at sea-orm-sync/src/driver/sqlx_sqlite.rs:448
"TEXT" => Value::String(
row.try_get::<Option<String>, _>(c.ordinal())
.expect("Failed to get string")
.map(Box::new),
),
"BLOB" => Value::Bytes(
row.try_get::<Option<Vec<u8>>, _>(c.ordinal())
.expect("Failed to get bytes")
.map(Box::new),
),
#[cfg(feature = "with-chrono")]
"DATETIME" => {
use chrono::{DateTime, Utc};
Value::ChronoDateTimeUtc(
row.try_get::<Option<DateTime<Utc>>, _>(c.ordinal())
.expect("Failed to get timestamp")
.map(Box::new),
)
}
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"DATETIME" => {
use time::OffsetDateTime;
Value::TimeDateTimeWithTimeZone(
row.try_get::<Option<OffsetDateTime>, _>(c.ordinal())
.expect("Failed to get timestamp")
.map(Box::new),
)
}
#[cfg(feature = "with-chrono")]
"DATE" => {
use chrono::NaiveDate;
Value::ChronoDate(
row.try_get::<Option<NaiveDate>, _>(c.ordinal())
.expect("Failed to get date")View on GitHub (pinned to e29bcd1b41)
Solutions
- Normalize stored timestamps to RFC3339 with UTC offset (e.g. strftime('%Y-%m-%dT%H:%M:%SZ', col)) or re-write via datetime(col)
- Write timestamps through chrono-typed entity fields so sqlx serializes the expected format
- Check for NULL/epoch-integer values in the column and fix them before querying via ProxyRow
- Propagate the sqlx error with column context instead of .expect and fall back to string values
Example fix
// before
Value::ChronoDateTimeUtc(
row.try_get::<Option<DateTime<Utc>>, _>(c.ordinal())
.expect("Failed to get timestamp")
.map(Box::new),
)
// after
Value::ChronoDateTimeUtc(
row.try_get::<Option<DateTime<Utc>>, _>(c.ordinal())
.unwrap_or_else(|e| panic!("Failed to get timestamp for col {} ({}): {}", c.name(), c.type_info().name(), e))
.map(Box::new),
) // root fix: ensure stored text is RFC3339, e.g. UPDATE t SET col = strftime('%Y-%m-%dT%H:%M:%SZ', col) Defensive patterns
Strategy: validation
Validate before calling
// Verify DATETIME columns store RFC3339-parseable UTC timestamps:
// SELECT col FROM t WHERE datetime(col) IS NULL AND col IS NOT NULL;
fn parses_as_utc(s: &str) -> bool { chrono::DateTime::parse_from_rfc3339(s).is_ok() } Type guard
fn is_rfc3339(s: &str) -> bool { chrono::DateTime::parse_from_rfc3339(s).is_ok() } Try / catch
let row = std::panic::catch_unwind(|| proxy_query(db)).unwrap_or_else(|_| fallback_row());
Prevention
- Write timestamps via chrono-typed entity fields so sqlx uses RFC3339
- Normalize foreign-written timestamps with strftime to ISO format
- Keep with-chrono vs with-time consistent across write/read paths
- Reject non-RFC3339 values at ingest time
When it happens
Trigger: Reading a SQLite DATETIME column whose stored text is not parseable as DateTime<Utc> (e.g. '2024-01-02 03:04:05' without offset or 'T' separator, unix epoch integers, naive local time) under the with-chrono feature.
Common situations: Timestamps written by other tools/libraries in SQLite's default 'YYYY-MM-DD HH:MM:SS' format; epoch seconds stored as INTEGER in a DATETIME column; values written by Python/Ruby ORMs with different formats; switching between with-chrono and with-time features.
Related errors
- Failed to get boolean
- Failed to get integer
- Failed to get big integer
- Failed to get double
- Failed to get string
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/8e71434673a6ea55.
Report an issue: GitHub.