tracel-ai/burn · error

Should be int, got float

Error message

Should be int, got float

What it means

BackendTensor::int() was called on a Float tensor handle. Only the Int variant can be unwrapped to the int primitive, so the dispatch layer panics. A float tensor reached a code path (indexing, scatter/gather, comparison output handling, etc.) that requires integer tensors.

Source

Thrown at crates/burn-dispatch/src/tensor.rs:64

        }
    }
    /// Returns the inner float tensor primitive.
    pub fn as_float(&self) -> &B::FloatTensorPrimitive {
        match self {
            BackendTensor::Float(tensor) => tensor,
            BackendTensor::Int(_) => panic!("Should be float, got int"),
            BackendTensor::Bool(_) => panic!("Should be float, got bool"),
            BackendTensor::Quantized(_) => panic!("Should be float, got quantized"),
            #[cfg(feature = "autodiff")]
            BackendTensor::Autodiff(_) => panic!("Should be float, got autodiff"),
        }
    }

    /// Returns the inner int tensor primitive.
    pub fn int(self) -> B::IntTensorPrimitive {
        match self {
            BackendTensor::Int(tensor) => tensor,
            BackendTensor::Float(_) => panic!("Should be int, got float"),
            BackendTensor::Bool(_) => panic!("Should be int, got bool"),
            BackendTensor::Quantized(_) => panic!("Should be int, got quantized"),
            #[cfg(feature = "autodiff")]
            BackendTensor::Autodiff(_) => panic!("Should be int, got autodiff"),
        }
    }

    /// Returns the inner bool tensor primitive.
    pub fn bool(self) -> B::BoolTensorPrimitive {
        match self {
            BackendTensor::Bool(tensor) => tensor,
            BackendTensor::Float(_) => panic!("Should be bool, got float"),
            BackendTensor::Int(_) => panic!("Should be bool, got int"),
            BackendTensor::Quantized(_) => panic!("Should be bool, got quantized"),
            #[cfg(feature = "autodiff")]
            BackendTensor::Autodiff(_) => panic!("Should be bool, got autodiff"),
        }
    }

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Cast the float tensor to int explicitly (tensor.int() / cast to DType::I32 or I64) before the int-only call
  2. Ensure the op generating the tensor is configured with an integer dtype (e.g. arange default dtype)
  3. Match on the BackendTensor variant at the call site instead of assuming Int
  4. Validate dtype at the API boundary using TensorMetadata and reject float inputs where ints are required

Example fix

// before
let idx = handle.int(); // panics: handle is Float
// after
let idx = handle.float().int(); // explicit float -> int cast, or build indices with int dtype from the start
Defensive patterns

Strategy: type-guard

Validate before calling

if !matches!(handle, BackendTensor::Int(_)) {
    panic!("expected int tensor (indices), got {:?}", handle.dtype());
}

Type guard

fn is_int<B: BackendTypes>(t: &BackendTensor<B>) -> bool {
    matches!(t, BackendTensor::Int(_))
}

Prevention

When it happens

Trigger: Calling int() on a tensor produced by float ops (arange with float dtype, float constants, division results); passing float values where integer indices or integer outputs are required (e.g. indices for gather/scatter, reshape with int tensor, embedding lookup).

Common situations: Computing indices with float math and forgetting to cast down; a config constant typed as f32 used as an index; upstream library change turned an int output into a float output; loading tensor data whose dtype inferred to float.

Related errors


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