dbt-labs/dbt-core · error
invalid serialized timestamp precision
Error message
invalid serialized timestamp precision
What it means
Panic from `parse::<u8>().expect("invalid serialized timestamp precision")` in `is_timestamp_ntz`. Field names encoded as `timestamp_ntz:<u8>` must carry a numeric precision suffix that fits u8 and TimePrecision's constraints; a non-numeric, empty, or out-of-range suffix makes the parse fail and panics.
Source
Thrown at crates/dbt-adapter/src/sql_types.rs:1085
.expect("string prefix checked")
.parse::<u8>()
.expect("invalid serialized time precision"),
))
}
_ => IsTimestamp::No,
}
}
pub fn is_timestamp_ntz(data_type: &DataType) -> IsTimestamp {
match data_type {
DataType::FixedSizeList(field, 1) if field.name().starts_with("timestamp_ntz:") => {
IsTimestamp::Yes(TimePrecision::new(
field
.name()
.strip_prefix("timestamp_ntz:")
.expect("string prefix checked")
.parse::<u8>()
.expect("invalid serialized timestamp precision"),
))
}
_ => IsTimestamp::No,
}
}
pub fn is_timestamp_ltz(data_type: &DataType) -> IsTimestamp {
match data_type {
DataType::FixedSizeList(field, 1) if field.name().starts_with("timestamp_ltz:") => {
IsTimestamp::Yes(TimePrecision::new(
field
.name()
.strip_prefix("timestamp_ltz:")
.expect("string prefix checked")
.parse::<u8>()
.expect("invalid serialized timestamp precision"),
))
}View on GitHub (pinned to 0267ce9170)
Solutions
- Correct the field name to a valid precision (e.g. `timestamp_ntz:6` for microseconds) at the serialization site.
- Regenerate stale recordings/fixtures with the current serializer rather than editing field names manually.
- Check for version drift between the component that wrote the schema and the one reading it; align the encoding format.
- Harden the reader: map parse failure to a proper error or IsTimestamp::No with a log instead of panicking.
Example fix
// before
.parse::<u8>()
.expect("invalid serialized timestamp precision"),
// after
.parse::<u8>().map_err(|_| panic!(
"invalid serialized timestamp precision in '{}'", field.name())).unwrap(), Defensive patterns
Strategy: validation
Validate before calling
fn validate_ntz_precision(name: &str) -> Result<u8, String> {
name.strip_prefix("timestamp_ntz:")
.ok_or_else(|| format!("not an ntz field: {name}"))?
.parse::<u8>()
.map_err(|e| format!("bad ntz precision in '{name}': {e}"))
} Type guard
fn well_formed_ntz_type(dt: &DataType) -> bool {
matches!(dt, DataType::FixedSizeList(f, 1)
if f.name().strip_prefix("timestamp_ntz:").is_some_and(|s| s.parse::<u8>().is_ok()))
} Try / catch
let checked = std::panic::catch_unwind(|| is_timestamp_ntz(&data_type));
match checked {
Ok(ts) => use_timestamp(ts),
Err(_) => log::error!("malformed timestamp_ntz field name in schema"),
} Prevention
- Lint fixtures for `timestamp_ntz:` names whose suffix is not a valid u8.
- Validate schemas at deserialization time (Arrow IPC readers) before they reach type mapping.
- Keep the precision encoding documented and shared between writer and reader code paths.
When it happens
Trigger: Calling `is_timestamp_ntz` with a FixedSizeList(1) whose field name is like `timestamp_ntz:abc`, `timestamp_ntz:`, `timestamp_ntz:256`, or `timestamp_ntz:3.0` — i.e. malformed serialized NTZ timestamp metadata.
Common situations: Corrupted or hand-edited Arrow schema fixtures, recordings produced by a mismatched dbt/adapter version, typo when constructing synthetic schemas for Snowflake NTZ columns in tests.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid serialized time precision
- string prefix checked
- Schema not found for canonical FQN: {}
- `EnterGuard` values dropped out of order. Guards returned by
- {e} {:?}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/51e37b73e4e104d2.
Report an issue: GitHub.