tracel-ai/burn · error

deserialize_char is not implemented

Error message

deserialize_char is not implemented

What it means

The nested-value deserializer does not implement serde's `deserialize_char`; it intentionally panics. NestedValue has no char variant, so any record type containing a `char` field (or a char-typed value reached via forward_to_deserialize_any) aborts with this unimplemented!().

Source

Thrown at crates/burn-store/src/nested/de.rs:245

        V: Visitor<'de>,
    {
        let val = self.extract_scalar("f32", |v| v.clone().as_f32())?;
        visitor.visit_f32(val)
    }

    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        let val = self.extract_scalar("f64", |v| v.clone().as_f64())?;
        visitor.visit_f64(val)
    }

    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        unimplemented!("deserialize_char is not implemented")
    }

    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        match self.value {
            Some(NestedValue::String(val)) => visitor.visit_str(&val),
            Some(other) => Err(custom_err(format!("expected str but got {other:?}"))),
            None => Err(custom_err("expected str, found nothing")),
        }
    }

    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        unimplemented!("deserialize_bytes is not implemented")

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Change the char field to String and validate/extract a single character after deserialization.
  2. Use #[serde(deserialize_with)] to read a string of length 1 and parse it into a char.
  3. Regenerate the checkpoint to match the supported record schema.
  4. Keep record item types limited to primitives supported by NestedValue (strings, ints, floats, bools, vecs, maps, options).

Example fix

// before
struct Item { grade: char } // -> deserialize_char panic
// after
struct Item { grade: String }
impl Item { fn grade(&self) -> char { self.grade.chars().next().unwrap() } }
Defensive patterns

Strategy: validation

Validate before calling

// Replace char fields with String at the serde level:
fn char_from_string<'de, D: serde::Deserializer<'de>>(d: D) -> Result<char, D::Error> {
    let s = String::deserialize(d)?;
    s.chars().next().ok_or_else(|| serde::de::Error::custom("empty string, expected char"))
}

Try / catch

let record = std::panic::catch_unwind(|| from_nested_value::<MyItem>(value.clone()))
    .map_err(|_| "record contains char: not supported by nested deserializer");

Prevention

When it happens

Trigger: Loading a Burn module record whose type includes a `char` field, causing serde to invoke Deserializer::deserialize_char during nested-value deserialization.

Common situations: Record item structs that changed to include char fields across Burn versions; user-defined metadata structs with character flags; checkpoint schema drift after a Burn upgrade.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/390c324efb3e1f22. Report an issue: GitHub.