tracel-ai/burn · error

Expected bool handle, got {}

Error message

Expected bool handle, got {}

What it means

`NdArray::bool_tensor` (BackendIr) panics when the TensorHandle's `HandleKind` is not `HandleKind::Bool` — a Float, Int, or Quantized handle was passed where a boolean mask tensor was expected. This fires during conversion of type-erased handles into bool tensor primitives (masks for masked_fill, where, etc.).

Source

Thrown at crates/burn-ndarray/src/backend.rs:151

    fn float_tensor(handle: TensorHandle<Self::Handle>) -> FloatTensor<Self> {
        match handle.handle {
            HandleKind::Float(handle) => handle,
            _ => panic!("Expected float handle, got {}", handle.handle.name()),
        }
    }

    fn int_tensor(handle: TensorHandle<Self::Handle>) -> IntTensor<Self> {
        match handle.handle {
            HandleKind::Int(handle) => handle,
            _ => panic!("Expected int handle, got {}", handle.handle.name()),
        }
    }

    fn bool_tensor(handle: TensorHandle<Self::Handle>) -> BoolTensor<Self> {
        match handle.handle {
            HandleKind::Bool(handle) => handle,
            _ => panic!("Expected bool handle, got {}", handle.handle.name()),
        }
    }

    fn quantized_tensor(handle: TensorHandle<Self::Handle>) -> QuantizedTensor<Self> {
        match handle.handle {
            HandleKind::Quantized(handle) => handle,
            _ => panic!("Expected quantized handle, got {}", handle.handle.name()),
        }
    }

    fn float_tensor_handle(tensor: FloatTensor<Self>) -> Self::Handle {
        HandleKind::Float(tensor)
    }

    fn int_tensor_handle(tensor: IntTensor<Self>) -> Self::Handle {
        HandleKind::Int(tensor)
    }

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Convert the mask to bool in the frontend: `mask.bool()` or compare with `mask.equal_elem(1.0)` to get a proper bool tensor.
  2. Use the accessor matching the handle's actual kind (`float_tensor`/`int_tensor`) in custom backend code.
  3. Fix the TensorKind registration so mask tensors are declared as Bool.
  4. Inspect the producing op of the mask to see why it yields a non-bool dtype.

Example fix

// before
let masked = x.mask_fill(float_mask, 0.0); // panics inside bool_tensor
// after
let masked = x.mask_fill(float_mask.greater_elem(0.5), 0.0); // bool mask
Defensive patterns

Strategy: type-guard

Validate before calling

fn ensure_bool_mask(t: &TensorIr) -> Result<(), String> {
    (t.kind == TensorKind::Bool && t.dtype == DType::Bool)
        .then_some(())
        .ok_or_else(|| format!("expected bool mask, got kind {:?} dtype {:?}", t.kind, t.dtype))
}

Type guard

fn as_bool_handle(h: HandleKind<NdArray>) -> Option<ArrayHandle> {
    match h { HandleKind::Bool(a) => Some(a), _ => None }
}

Try / catch

let b = std::panic::catch_unwind(|| NdArray::bool_tensor(th))
    .map_err(|_| anyhow!("handle is not bool; expected {}", th.handle.name()))?;

Prevention

When it happens

Trigger: Calling `NdArray::bool_tensor(handle)` (or `get_bool_tensor`) with a non-bool handle; commonly a float tensor (e.g. result of a comparison done in float, or 0.0/1.0 mask) is passed where a bool mask is required.

Common situations: Passing a 0/1 float mask instead of a bool mask to masked_fill/where; registering a mask tensor with the wrong TensorKind in custom IR; frontend code comparing tensors without casting the result to bool.

Related errors


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