SeaQL/sea-orm · error

Failed to get timestamptz

Error message

Failed to get timestamptz

What it means

Under the `with-chrono` feature, a column typed `TIMESTAMPTZ` is decoded with `try_get::<Option<chrono::DateTime<chrono::Utc>>>`; when sqlx returns a decode error, `.expect("Failed to get timestamptz")` panics. This means the wire data for the column could not be interpreted as a timestamptz-compatible value.

Source

Thrown at sea-orm-sync/src/driver/sqlx_postgres.rs:830

                            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

  1. Verify the column type is genuinely `timestamp with time zone` (`\d table` or information_schema).
  2. Enable `with-chrono` on sea-orm-sync and ensure sqlx is compiled with its `chrono` feature at a compatible version.
  3. If the column is plain `timestamp`, either change the Rust mapping/query or alter the column to timestamptz.
  4. As a fallback, cast in SQL (`col::timestamptz`) or select as text and parse with chrono.

Example fix

// before: column is timestamp (no tz), decoded as DateTime<Utc> -> panic
// SELECT created_at FROM events;

// after
// ALTER TABLE events ALTER COLUMN created_at TYPE timestamptz USING created_at AT TIME ZONE 'UTC';
// or: SELECT created_at::timestamptz AS created_at FROM events;
Defensive patterns

Strategy: validation

Validate before calling

let ty: (String,) = sqlx::query_as(
    "SELECT udt_name FROM information_schema.columns WHERE table_name = $1 AND column_name = $2",
).bind("events").bind("created_at").fetch_one(db).await?;
if ty.0 != "timestamptz" { return Err(anyhow!("created_at is {} ({}), expected timestamptz", ty.0, "chrono decode will fail")); }

Type guard

fn is_timestamptz(udt_name: &str) -> bool { udt_name == "timestamptz" }

Try / catch

// avoid the panic by decoding with error handling:
let ts = row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(idx)
    .map_err(|e| DecodeError::Timestamptz(e.to_string()))?;

Prevention

When it happens

Trigger: Selecting a TIMESTAMPTZ column via ProxyRow when the underlying column is actually TIMESTAMP (without tz) with an unexpected encoding, a custom type named TIMESTAMPTZ in a foreign schema, or sqlx's chrono decoding of that OID is unavailable.

Common situations: Schema drift after migrations, querying through FDWs/views where types resolve differently, Postgres/extension version changes, or sqlx version misalignment with sea-orm.

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