{"record":{"id":"6f5d181f4bfb8176","repo":"tracel-ai/burn","slug":"deserialize-any-is-not-implemented","errorCode":null,"errorMessage":"deserialize_any is not implemented","messagePattern":"deserialize_any is not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-store/src/nested/de.rs","lineNumber":67,"sourceCode":"        let value = self\n            .value\n            .ok_or_else(|| custom_err(format!(\"expected {expected}, found nothing\")))?;\n\n        match extractor(&value) {\n            Some(val) => Ok(val),\n            None => Err(custom_err(format!(\"expected {expected} but got {value:?}\"))),\n        }\n    }\n}\n\nimpl<'de, A: BurnModuleAdapter> serde::Deserializer<'de> for Deserializer<A> {\n    type Error = Error;\n\n    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        unimplemented!(\"deserialize_any is not implemented\")\n    }\n\n    fn deserialize_struct<V>(\n        self,\n        name: &'static str,\n        fields: &'static [&'static str],\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        let value = match self.value {\n            Some(value) => {\n                // Adapt modules\n                if let Some(name) = name.strip_suffix(RECORD_ITEM_SUFFIX) {\n                    A::adapt(name, value)\n                } else {\n                    value","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-store/src/nested/de.rs#L49-L85","documentation":"Burn's nested-value serde Deserializer (crates/burn-store/src/nested/de.rs) implements only the concrete deserialize_* methods it supports (struct, map, seq, i16, i32, i64, str, etc.) and deliberately panics in deserialize_any. Because the format is not self-describing in a generic way, any type whose Deserialize impl falls back to deserialize_any triggers this panic during record loading.","triggerScenarios":"Deserializing a type from a Burn nested value (e.g., ModuleRecorder load / store record deserialization) whose serde Deserialize implementation relies on the generic `deserialize_any` entry point instead of a type-specific method — e.g., #[serde(untagged)] enums, deserializing into serde_json::Value, or serde data formats forwarding to any.","commonSituations":"Loading a Burn module record where a field's type changed to something requiring untagged/any-based deserialization; custom adapters or record items containing arbitrary JSON-like values; using the nested deserializer for types it was never designed for (it only supports the shapes Burn record items use).","solutions":["Ensure the type being deserialized is a struct/map/seq/primitive that serde deserializes via type-specific methods, not via deserialize_any.","Replace untagged or internally-tagged enum fields in the record type with explicit tagged structs that use deserialize_struct/deserialize_enum.","If you own the Deserialize impl, add #[serde(deserialize_with = ...)] or a manual impl that calls concrete deserialize_* methods.","Check for a version change: a Burn upgrade may have changed record item types; adapt checkpoints with a BurnModuleAdapter."],"exampleFix":"// before\n#[derive(Deserialize)]\n#[serde(untagged)]\nenum Value { Int(i32), Text(String) } // untagged -> deserialize_any -> panic\n// after\n#[derive(Deserialize)]\n#[serde(rename_all = \"snake_case\")]\nenum Value { Int(i32), Text(String) } // externally tagged -> deserialize_enum is implemented","handlingStrategy":"type-guard","validationCode":"// Only deserialize record item types built from structs/enums with explicit tags;\n// audit #[derive(Deserialize)] types for untagged enums or Value-like fields before use.","typeGuard":"fn nested_deserialize_safe<T: DeserializeOwned>() -> bool {\n    // Safe if T's impl never requires deserialize_any:\n    // no #[serde(untagged)], no serde_json::Value / DynamicValue fields.\n    !std::any::TypeId::of::<T>().needs_any() // conceptual: audit manually\n}","tryCatchPattern":"// unimplemented! panics are not catchable via Result; only catch_unwind helps\nlet result = std::panic::catch_unwind(|| load_record(path));\nmatch result {\n    Ok(Ok(record)) => record,\n    _ => eprintln!(\"nested deserializer hit an unsupported type (deserialize_any)\"),\n}","preventionTips":["Keep record item types to named structs, externally tagged enums, options, vecs, and supported primitives.","Avoid #[serde(untagged)] and serde_json::Value fields in record types.","Test save/load round trips whenever a record item type changes."],"tags":["rust","serde","deserialization","burn","panic"],"backgroundTag":"deserialize-any-unsupported","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}