tracel-ai/burn · error

Optimizer record tensors should carry a parameter id.

Error message

Optimizer record tensors should carry a parameter id.

What it means

When loading an optimizer record, each `RecordTensor` must carry a `param_id` so its state can be re-attached to the right parameter. `param_id.expect("Optimizer record tensors should carry a parameter id.")` panics when a tensor in the record has no id. This guards against hand-crafted or legacy/malformed `OptimizerRecord` data where the id field was never set.

Source

Thrown at crates/burn-optim/src/optim/module/module_optimizer.rs:277

                ranks.insert(id, rank);
            }
        }

        for (name, path) in record.paths.iter() {
            if let Ok(id) = name.parse::<u64>() {
                paths.insert(id, path.to_string());
            }
        }

        let mut source = StateSource::new(record.scalars);

        for tensor in record.tensors {
            let RecordTensor {
                name,
                param_id,
                data,
            } = tensor;
            let id = param_id.expect("Optimizer record tensors should carry a parameter id.");
            // Fall back to inferring rank from a tensor shape if no `__rank` scalar was present.
            ranks.entry(id).or_insert(data.shape.len());
            source.insert_tensor(name, data);
        }

        let mut states = HashMap::new();
        for (id, rank) in ranks {
            let prefix = id.to_string();
            let path = paths.get(&id);
            let (optim, grad_clipping) =
                self.optim_from_param(id.into(), path.map(|path| path.as_str()));
            // Skip parameters whose state can't be reconstructed (truncated/foreign record); they
            // are re-initialized lazily on the next step rather than aborting the load.
            if let Some(state) = optim.state_unflatten(rank, &prefix, &mut source, &device) {
                states.insert(
                    ParamId::from(id),
                    OptimizationContext {
                        optim: optim.clone(),

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Regenerate the checkpoint with the current burn version so every tensor carries a `param_id`.
  2. If building `OptimizerRecord` manually, set `param_id` on every `RecordTensor` before `load_record`.
  3. Write a migration that infers/assigns ids from tensor names for old checkpoints.
  4. Validate the record (all tensors have Some(param_id)) before calling `load_record`.

Example fix

// before
RecordTensor { name: "momentum", param_id: None, data }
// after
RecordTensor { name: "momentum", param_id: Some(param_id.clone()), data }
Defensive patterns

Strategy: validation

Validate before calling

fn validate_record(record: &OptimizerRecord) -> Result<(), String> {
    if record.tensors.iter().any(|t| t.param_id.is_none()) {
        return Err("record contains tensors without param_id".into());
    }
    Ok(())
}
validate_record(&record)?;

Prevention

When it happens

Trigger: Calling `load_record` with an `OptimizerRecord` whose `tensors` contain a `RecordTensor` with `param_id: None` — e.g. a record built manually, produced by an older/other serialization format, or corrupted during storage.

Common situations: Deserializing a checkpoint from an older burn version before `param_id` was added; hand-assembling `OptimizerRecord` in tests/tools and forgetting to set `param_id`; truncated or corrupted checkpoint files that deserialize but lack ids.

Related errors


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