dbt-labs/dbt-core · error

Failed to deserialize

Error message

Failed to deserialize

What it means

This is a test assertion panic from `expect("Failed to deserialize")` on `HashMap::from_recording_json(&json)`. The time-machine recording layer serializes a map of `AdapterResult<Arc<Schema>>` to JSON and must reconstruct it on replay; if the recorded JSON does not round-trip into the same map (bad/missing type tags, unrepresentable complex types, schema field loss), the deserializer returns an error and this expect panics the test. It indicates a gap in the recording JSON codec for the schema payloads in `crates/dbt-adapter/src/time_machine/metadata.rs:838`.

Source

Thrown at crates/dbt-adapter/src/time_machine/metadata.rs:838

                DataType::FixedSizeList(
                    Arc::new(Field::new(
                        "item",
                        DataType::Timestamp(TimeUnit::Microsecond, None),
                        true,
                    )),
                    1,
                ),
                true,
            ),
        ]));
        map.insert("test.schema.complex".to_string(), Ok(schema));

        // Serialize to JSON
        let json = map.to_recording_json();

        // Deserialize back
        let deserialized: HashMap<String, AdapterResult<Arc<Schema>>> =
            HashMap::from_recording_json(&json).expect("Failed to deserialize");

        // Verify roundtrip
        assert_eq!(map.len(), deserialized.len());
        let original_schema = map.get("test.schema.complex").unwrap().as_ref().unwrap();
        let result_schema = deserialized
            .get("test.schema.complex")
            .unwrap()
            .as_ref()
            .unwrap();

        // Compare field by field
        assert_eq!(original_schema.fields().len(), result_schema.fields().len());
        for (orig, res) in original_schema.fields().iter().zip(result_schema.fields()) {
            assert_eq!(orig.name(), res.name(), "Field name mismatch");
            assert_eq!(
                orig.data_type(),
                res.data_type(),
                "DataType mismatch for field {}",

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Run the failing test with RUST_BACKTRACE=1 to see the underlying serde/deserialization error returned by from_recording_json.
  2. Inspect the JSON produced by `to_recording_json` for the failing key (test.schema.complex) and compare against what from_recording_json expects (type tags, AdapterResult wrappers).
  3. Extend the recording JSON (de)serializer in metadata.rs to support the complex type that fails, so serialize and deserialize are symmetric.
  4. Regenerate any stale recordings with the current code version before running replay tests.
  5. If the schema itself is unsupported, either normalize it before recording or mark the test case as unsupported for recording.

Example fix

// before
let deserialized: HashMap<String, AdapterResult<Arc<Schema>>> =
    HashMap::from_recording_json(&json).expect("Failed to deserialize");
// after (debug first, then fix codec)
let deserialized = HashMap::from_recording_json(&json)
    .unwrap_or_else(|e| panic!("Failed to deserialize: {e}; json={json}"));
Defensive patterns

Strategy: validation

Validate before calling

if let Err(e) = HashMap::<String, AdapterResult<Arc<Schema>>>::from_recording_json(&json) {
    eprintln!("recording not deserializable: {e}");
    // regenerate or reject the recording before use
}

Type guard

fn is_deserializable_recording(json: &serde_json::Value) -> bool {
    json.get("__type__").is_some()
}

Try / catch

match HashMap::from_recording_json(&json) {
    Ok(map) => map,
    Err(e) => { log::error("schema recording deserialize failed: {e}"); regenerate_recording() }
}

Prevention

When it happens

Trigger: Calling `HashMap::from_recording_json` on output of `to_recording_json` where the JSON contains schema types the deserializer cannot reconstruct (e.g. complex/nested types in test_schema_roundtrip_with_complex_types), or where the `__type__` markers/AdapterResult wrappers were dropped during serialization.

Common situations: Adding a new Arrow/Schema field type without extending the recording serializer; a schema type whose serde representation changed between versions so older recordings no longer parse; running replay tests against recordings produced by a different build.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/da807f03ccea4ece. Report an issue: GitHub.