SeaQL/sea-orm · error
Failed to get timestamptz
Error message
Failed to get timestamptz
What it means
This is a panic raised inside sea-orm's ProxyRow conversion when decoding a PostgreSQL TIMESTAMPTZ column. sqlx's `try_get` failed to produce an `Option<chrono::DateTime<Utc>>`, and the code path uses `.expect(...)` instead of returning an error, so the library panics. It almost always means the value in the database cannot be decoded into the expected timestamp-with-timezone type (underlying type mismatch, unrepresentable sentinel value, or a column whose actual type differs from the reported TIMESTAMPTZ).
Source
Thrown at src/driver/sqlx_postgres.rs:843
feature = "postgres-array"
))]
"TIME[]" => Value::Array(
sea_query::ArrayType::TimeTime,
row.try_get::<Option<Vec<time::Time>>, _>(c.ordinal())
.expect("Failed to get time array")
.map(|vals| {
Box::new(
vals.into_iter()
.map(|val| Value::TimeTime(Some(val)))
.collect(),
)
}),
),
#[cfg(feature = "with-chrono")]
"TIMESTAMPTZ" => Value::ChronoDateTimeUtc(
row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())
.expect("Failed to get timestamptz"),
),
#[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
"TIMESTAMPTZ" => Value::TimeDateTimeWithTimeZone(
row.try_get::<Option<time::OffsetDateTime>, _>(c.ordinal())
.expect("Failed to get timestamptz"),
),
#[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
"TIMESTAMPTZ[]" => Value::Array(
sea_query::ArrayType::ChronoDateTimeUtc,
row.try_get::<Option<Vec<chrono::DateTime<chrono::Utc>>>, _>(
c.ordinal(),
)
.expect("Failed to get timestamptz array")
.map(|vals| {
Box::new(
vals.into_iter()
.map(|val| Value::ChronoDateTimeUtc(Some(val)))View on GitHub (pinned to e29bcd1b41)
Solutions
- Verify the actual PostgreSQL column type with `\d table` or `SELECT column_name, data_type FROM information_schema.columns` and confirm it is really `timestamp with time zone`; cast in SQL (`col::timestamptz`) if the expression's reported type differs.
- Align sea-orm features with your types: enable `with-chrono` and keep the chrono/time feature set consistent across the workspace.
- Bump sea-orm and sqlx to matching, current versions — older sqlx versions had known failures decoding certain TIMESTAMPTZ values (e.g. infinity/negative-infinity timestamps or unusual offsets).
- If decoding `infinity`/`-infinity` sentinels, replace those values with NULL or concrete timestamps (`UPDATE t SET col = NULL WHERE col = 'infinity'::timestamptz`), since neither chrono nor time can represent them.
- As a workaround, select the column as text (`col::text`) and parse it manually in application code instead of relying on ProxyRow's type-based decode.
Example fix
// before (fails: expression reports timestamptz but value is not decodable)
let rows = MyEntity::find().from_raw_sql(Statement::from_string(
DbBackend::Postgres, "SELECT now() AS created FROM t"
)).into_model::<MyModel>().all(&db).await?;
// after: force an unambiguous, decodable type in SQL
let rows = MyEntity::find().from_raw_sql(Statement::from_string(
DbBackend::Postgres, "SELECT now()::timestamptz AS created FROM t"
)).into_model::<MyModel>().all(&db).await?; Defensive patterns
Strategy: validation
Validate before calling
// Run before decoding: ensure the column really is timestamptz and values are decodable
let ok = sqlx::query_scalar::<_, bool>(
"SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name=$1 AND column_name=$2 AND data_type='timestamp with time zone')"
).bind(table).bind(column).fetch_one(&db).await?;
if !ok { return Err(AppError::SchemaMismatch("expected timestamptz")); }
// additionally scrub sentinels:
// UPDATE t SET col = NULL WHERE col IN ('infinity'::timestamptz, '-infinity'::timestamptz); Type guard
fn is_timestamptz(meta: &sea_orm::ColumnMeta) -> bool {
meta.col_type.as_str().eq_ignore_ascii_case("TIMESTAMPTZ")
} Try / catch
// sea-orm panics here rather than returning Err; isolate the call and convert
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
entity::Entity::find().from_raw_sql(stmt).into_model::<M>().all(&db)
}));
match result {
Ok(res) => res?,
Err(_) => return Err(AppError::DecodeFailed("timestamptz column undecodable")),
} Prevention
- Cast ambiguous expressions to ::timestamptz explicitly in raw SQL.
- Prefer `timestamptz` over `timestamp` for all timestamp columns.
- Never store `infinity`/`-infinity` sentinel timestamps; use NULL.
- Keep sea-orm and sqlx versions in lockstep across the workspace.
- Enable the `with-chrono` feature when your models use chrono types.
When it happens
Trigger: Querying/fetching a row from PostgreSQL where a column with type name TIMESTAMPTZ cannot be decoded by sqlx into Option<chrono::DateTime<Utc>> — e.g. via `find()`, `from_raw_sql`/`Statement` selects, ProxyRow/into_model decoding, or custom SELECTs whose column metadata says TIMESTAMPTZ but whose value is of another type or encoding.
Common situations: Selecting `now()`/`clock_timestamp()` expressions whose metadata mismatches, columns actually declared `timestamp` or custom domain types over timestamptz, reading via raw SQL where aliases change inferred type, storing `infinity`/`-infinity` timestamp sentinels, or sqlx/sea-orm version upgrades changing supported timestamp encodings.
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
- Failed to get float
- Failed to get double
- Failed to get timestamptz
- Failed to get timestamptz array
- Failed to get timetz
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/c6087dbec007d883.
Report an issue: GitHub.