dbt-labs/dbt-core · error
original value should be serializable via the time-machine r
Error message
original value should be serializable via the time-machine registry
What it means
Panic from `serialize_object(original).expect("original value should be serializable via the time-machine registry")` in the shared helper `assert_reserialization_fixed_point` (serializable_impls.rs:858). The helper verifies that a minijinja Value (Column or RelationObject) recorded by the time machine survives serialize -> deserialize -> re-serialize unchanged. serialize_object looks types up by TYPE_ID in the registry and returns None when the value's concrete type is not registered, so the expect panics — meaning replay cannot even record this object.
Source
Thrown at crates/dbt-adapter/src/time_machine/serializable_impls.rs:858
// let j1 = serialize(original);
// let restored = deserialize(j1);
// let j2 = serialize(restored);
// assert_eq!(j1, j2); // <-- the invariant replay depends on
//
// The existing `*_roundtrip` tests only check accessors after ONE
// deserialize; they do NOT assert this fixed point.
// =========================================================================
/// Assert `serialize(deserialize(serialize(original))) == serialize(original)`.
///
/// `original` must already be a serializable jinja Value (i.e. `serialize_object`
/// returns `Some`). Returns the first serialization for optional further checks.
fn assert_reserialization_fixed_point(
original: &minijinja::Value,
ctx: &ReplayCallContext,
) -> serde_json::Value {
let j1 = serialize_object(original)
.expect("original value should be serializable via the time-machine registry");
let restored = json_to_value_with_context(&j1, ctx);
let j2 = serialize_object(&restored).expect(
"reconstructed value should re-serialize via the time-machine registry \
(if this is None, deserialize produced a non-registry type such as a plain map)",
);
assert_eq!(
j1, j2,
"reserialization must be a fixed point; serialize/deserialize are asymmetric.\n\
first: {j1:#}\n\
second: {j2:#}"
);
j1
}
#[test]
fn test_column_reserialization_fixed_point_snowflake_varchar() {
// A VARCHAR(255) column as returned by e.g. get_columns_in_relation.
let original = crate::column::Column::new(View on GitHub (pinned to 0267ce9170)
Solutions
- Check the object's TYPE_ID (e.g. `Column`, `RelationObject`) is registered in the time-machine serialization registry.
- For the failing fixture (Snowflake numeric/varchar or BigQuery nested struct), add serialization support for the unrepresentable field type.
- Ensure json_to_value_with_context reconstructs the registry type, not a plain map — the helper's second message diagnoses that case.
- Replace expect in the helper with context-rich panics that print the type id and payload to speed triage.
Example fix
// before
let j1 = serialize_object(original)
.expect("original value should be serializable via the time-machine registry");
// after
let j1 = serialize_object(original)
.unwrap_or_else(|| panic!("type {:?} not registered for time-machine serialization", original.type_name())); Defensive patterns
Strategy: type-guard
Validate before calling
if !is_registered_type(value) {
return Err(format!("{} is not registered for time-machine serialization", value.type_name()));
} Type guard
fn is_registered_type(v: &minijinja::Value) -> bool {
serialize_object(v).is_some()
} Try / catch
let j1 = serialize_object(original).unwrap_or_else(|| {
panic!("{} not serializable via time-machine registry", original.type_name())
}); Prevention
- Register TYPE_IDs for every new Column/RelationObject variant at introduction time.
- Add BigQuery struct/repeated-field fixtures to fixed-point tests.
- Ensure deserialize reconstructs registry types, never plain maps.
When it happens
Trigger: `serialize_object` called on minijinja Values wrapping Column (Snowflake varchar/numeric, BigQuery repeated/nested struct) or RelationObject (table, dynamic table) whose TYPE_ID is not registered, or whose struct fields cannot be converted to recorded JSON.
Common situations: Adding a new Column/RelationObject variant or field without registering it in the time-machine serialization registry; BigQuery nested/repeated struct fields lacking a recording representation; a deserialize path that returns a plain map instead of a registry type (then the second expect with the 'non-registry type' message fires).
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- unsupported numeric type for version
- version must be a string, integer, or float
- invalid serialized time precision
- invalid serialized timestamp precision
- Failed to deserialize
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/dfb39fdf1b9ba08a.
Report an issue: GitHub.