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
- Convert the mask to bool in the frontend: `mask.bool()` or compare with `mask.equal_elem(1.0)` to get a proper bool tensor.
- Use the accessor matching the handle's actual kind (`float_tensor`/`int_tensor`) in custom backend code.
- Fix the TensorKind registration so mask tensors are declared as Bool.
- 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
- Use typed frontend tensors (Tensor<B,D,bool>) so masks are bool at the type level
- Convert 0/1 float masks with .greater_elem(0.5) or .bool() before mask ops
- Register mask tensors as TensorKind::Bool in custom IR
- Never reuse a float tensor as a mask directly
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
- Expected float handle, got {}
- Expected int handle, got {}
- Expected quantized handle, got {}
- float_storage_as_f32: unsupported dtype {:?}
- conv1d: unsupported dtype {:?}
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/06062e3e61a070c3.
Report an issue: GitHub.