tracel-ai/burn · error

deserialize_tuple is not implemented

Error message

deserialize_tuple is not implemented

What it means

The nested-value deserializer panics on `deserialize_tuple` because anonymous tuples (e.g., `(i32, String)`) are not supported — only named struct fields, seqs, maps, and primitives are. Serde calls this method for tuple targets, hitting the deliberate unimplemented!().

Source

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

                    value,
                    self.default_for_missing_fields,
                )?),
                NestedValue::F32s(_) => visitor.visit_seq(VecSeqAccess::<A, f32>::new(
                    value,
                    self.default_for_missing_fields,
                )?),
                _ => Err(custom_err(format!("Expected Vec but got {value:?}"))),
            }
        } else {
            Err(custom_err("Expected Vec but got None"))
        }
    }

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

    fn deserialize_tuple_struct<V>(
        self,
        _name: &'static str,
        _len: usize,
        _visitor: V,
    ) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        unimplemented!("deserialize_tuple_struct is not implemented")
    }

    fn deserialize_enum<V>(
        self,
        _name: &'static str,
        variants: &'static [&'static str],

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Replace the tuple field with a named struct (e.g., struct Pair { first: T, second: U }) that deserializes via deserialize_struct.
  2. Use Vec<T> if the tuple is homogeneous, deserialized via deserialize_seq.
  3. Use #[serde(deserialize_with)] to convert a seq value into the tuple after loading.
  4. Regenerate the checkpoint to match the supported schema.

Example fix

// before
struct Item { dims: (usize, usize) } // -> deserialize_tuple panic
// after
#[derive(Deserialize)]
struct Dims { h: usize, w: usize }
struct Item { dims: Dims }
Defensive patterns

Strategy: validation

Validate before calling

// Convert tuples to named structs or deserialize via seq:
fn pair_from_seq<'de, D: serde::Deserializer<'de>>(d: D) -> Result<(usize, usize), D::Error> {
    let v: Vec<usize> = Vec::deserialize(d)?;
    match v.as_slice() { [a, b] => Ok((*a, *b)), _ => Err(serde::de::Error::custom("expected pair")) }
}

Try / catch

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

Prevention

When it happens

Trigger: Loading a Burn record whose type contains a tuple field (e.g., `(usize, usize)` for a shape pair, `(f32, f32)` coordinates), routing through Deserializer::deserialize_tuple.

Common situations: Record items with tuple-shaped metadata (pairs, triples); schema changes introducing tuple fields across Burn versions; user-defined record structs mirroring tuple returns from APIs.

Related errors


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