SeaQL/sea-orm · error

Failed to get timestamptz array

Error message

Failed to get timestamptz array

What it means

ProxyRow panics because sqlx failed to decode a PostgreSQL TIMESTAMPTZ[] (array of timestamptz) column into `Option<Vec<chrono::DateTime<Utc>>>`. This arm only compiles with both `with-chrono` and `postgres-array` features; the `.expect` turns the sqlx decode error into an unrecoverable panic. Typical root causes are the element type not actually being timestamptz, a differently-shaped array, or unsupported sentinel elements.

Source

Thrown at src/driver/sqlx_postgres.rs:857

                        #[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)))
                                        .collect(),
                                )
                            }),
                        ),
                        #[cfg(all(
                            feature = "with-time",
                            not(feature = "with-chrono"),
                            feature = "postgres-array"
                        ))]
                        "TIMESTAMPTZ[]" => Value::Array(
                            sea_query::ArrayType::TimeDateTimeWithTimeZone,
                            row.try_get::<Option<Vec<time::OffsetDateTime>>, _>(c.ordinal())
                                .expect("Failed to get timestamptz array")
                                .map(|vals| {

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Confirm the column/expression is genuinely `timestamptz[]` (`\d+ table` or information_schema); cast in SQL: `array_agg(ts)::timestamptz[]`.
  2. Ensure both `with-chrono` and `postgres-array` features are enabled in all crates that touch the entity, with a single active chrono/time family.
  3. Check array shape: multidimensional or mixed-type arrays won't decode; normalize the query (e.g. `unnest` or flatten) instead.
  4. Replace `infinity`/`-infinity` elements with NULL or real timestamps.
  5. Bump sea-orm/sqlx versions for known PG array decode fixes.
  6. Workaround: select as `array_to_json(col)` or text and deserialize manually.

Example fix

// before (element type reported as timestamptz[] but actually text[])
"SELECT array_agg(label) AS times FROM events"

// after
"SELECT array_agg(ts)::timestamptz[] AS times FROM events"
Defensive patterns

Strategy: validation

Validate before calling

// verify array element type before fetching
let elem = sqlx::query_scalar::<_, String>(
    "SELECT udt_name FROM information_schema.columns WHERE table_name=$1 AND column_name=$2"
).bind(table).bind(column).fetch_one(&db).await?;
if elem != "_timestamptz" { return Err(AppError::SchemaMismatch(format!("expected _timestamptz, got {elem}"))); }

Type guard

fn is_timestamptz_array(meta: &sea_orm::ColumnMeta) -> bool {
    meta.col_type.as_str().eq_ignore_ascii_case("TIMESTAMPTZ[]")
}

Try / catch

let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    entity::Entity::find().from_raw_sql(stmt).into_model::<M>().all(&db)
}));
let rows = res.map_err(|_| AppError::DecodeFailed("timestamptz[] decode panicked"))??;

Prevention

When it happens

Trigger: Fetching an array column (e.g. `timestamptz[]` in a model, or an aggregate like `array_agg(ts)` whose reported type is TIMESTAMPTZ[]) where the value cannot decode into Vec<DateTime<Utc>> — mismatched element types, multidimensional arrays, or `infinity` elements.

Common situations: array_agg/set-returning queries whose element type metadata is timestamptz[] but whose values are text; models typed `Vec<DateTime<Utc>>` against columns declared `text[]`; reading arrays through views; older sqlx versions with buggy PG array timestamp decoding.

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