tracel-ai/burn · error

Should be bool, got float

Error message

Should be bool, got float

What it means

BackendTensor::bool() was called on a Float tensor handle. Only the Bool variant can be unwrapped to a bool primitive, so the code panics. A float tensor reached a path expecting a boolean tensor, most often a mask/condition slot (where/masked_fill, comparison consumption).

Source

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

    }

    /// 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"),
        }
    }

    /// Returns the inner quantized tensor primitive.
    pub fn quantized(self) -> B::QuantizedTensorPrimitive {
        match self {
            BackendTensor::Quantized(tensor) => tensor,
            _ => unreachable!(),
        }
    }

    #[cfg(feature = "autodiff")]
    /// Returns the inner autodiff tensor primitive.
    pub fn autodiff(self) -> FloatTensor<Autodiff<B>> {

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Produce the mask via a comparison op (x.equal(y), x.lower(z)) instead of casting a float tensor
  2. If a numeric-to-bool conversion is truly intended, apply it through an explicit backend cast to DType::Bool rather than bool() on the enum
  3. Match the BackendTensor variant at the call site and handle Float deliberately
  4. Validate dtype via TensorMetadata before consuming mask/condition tensors

Example fix

// before
let mask = handle.bool(); // panics: Float variant
// after
let mask = handle.float().greater_elem(0.0); // build a real Bool mask via comparison
Defensive patterns

Strategy: type-guard

Validate before calling

if !matches!(handle, BackendTensor::Bool(_)) {
    panic!("expected bool mask, got {:?}", handle.dtype());
}

Type guard

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

Prevention

When it happens

Trigger: Calling bool() on a float tensor produced by float ops; passing float values (or 0.0/1.0 flags) where a boolean mask/condition is required; forgetting that comparison ops (==, <, >=) — not casts — produce Bool tensors.

Common situations: Using 0/1 float tensors as masks instead of comparison results; PyTorch-style implicit truthiness assumptions; upstream change replaced a Bool output with Float; custom kernels that assumed a mask input was Bool.

Related errors


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