tracel-ai/burn · error
deserialize_i8 is not implemented
Error message
deserialize_i8 is not implemented
What it means
The nested-value deserializer in burn-store does not implement serde's `deserialize_i8`; it panics with unimplemented!(). NestedValue-backed record deserialization only supports wider integer widths, so any struct field of type i8 (or an i8-typed enum payload) reached during record deserialization hits this panic.
Source
Thrown at crates/burn-store/src/nested/de.rs:167
"Expected map value but got {:?}",
self.value
))),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let val = self.extract_scalar("bool", |v| v.clone().as_bool())?;
visitor.visit_bool(val)
}
fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
unimplemented!("deserialize_i8 is not implemented")
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let val = self.extract_scalar("i16", |v| v.clone().as_i16())?;
visitor.visit_i16(val)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let val = self.extract_scalar("i32", |v| v.clone().as_i32())?;
visitor.visit_i32(val)
}
View on GitHub (pinned to d16f7ba2ed)
Solutions
- Change the field type in the record item from i8 to i16/i32/i64 and convert after deserialization.
- Wrap the i8 field with #[serde(deserialize_with)] using a function that reads an i16 and casts to i8.
- Regenerate/re-save the checkpoint so its record structure matches types the nested deserializer supports.
- Verify Burn version match between the code that saved the record and the code loading it.
Example fix
// before
#[derive(Deserialize)]
struct Item { flag: i8 } // -> deserialize_i8 panic
// after
#[derive(Deserialize)]
struct Item { flag: i16 }
impl Item { fn flag(&self) -> i8 { self.flag as i8 } } Defensive patterns
Strategy: validation
Validate before calling
// Reject i8 fields in record item structs before loading
fn assert_no_i8_fields<T>(_t: &T) { /* audit: grep record types for ": i8" */ }
// or deserialize_with:
fn i8_from_i16<'de, D: serde::Deserializer<'de>>(d: D) -> Result<i8, D::Error> {
Ok(i8::try_from(i16::deserialize(d)).map_err(serde::de::Error::custom)?)
} Try / catch
let record = std::panic::catch_unwind(|| from_nested_value::<MyItem>(value.clone()))
.unwrap_or_else(|_| panic!("record contains i8: not supported by nested deserializer")); Prevention
- Use i16/i32/i64 for integer fields in record item structs; cast to i8 afterwards.
- Round-trip test records after any field type change.
- Keep Burn versions matched between checkpoint writers and readers.
When it happens
Trigger: Loading a Burn module/record whose deserialized type contains an `i8` field, causing serde to call Deserializer::deserialize_i8 during `from_nested_value` / recorder load.
Common situations: A record item struct changed between Burn versions to include an i8 field; user-defined record items or custom adapters storing byte-sized values; loading checkpoints saved by newer Burn versions into older code (or vice versa) where field types differ.
Related errors
- deserialize_any is not implemented
- deserialize_u32 is not implemented
- deserialize_char is not implemented
- deserialize_bytes is not implemented
- deserialize_unit is not implemented
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/87ca42410c7686f2.
Report an issue: GitHub.