huggingface/candle · error
{} is a dummy type and does not support operations
Error message
{} is a dummy type and does not support operations What it means
Dummy types implement AddAssign by panicking: F6E2M3, F6E3M2, F4 and F8E8M0 are unimplemented placeholders and support no arithmetic. The impl exists only so generic code bounded by num-traits/std-ops compiles; executing += on them always aborts.
Source
Thrown at candle-core/src/dummy_dtype.rs:90
fn cpu_storage_as_slice(_s: &crate::CpuStorage) -> Result<&[Self]> {
Err(Error::UnsupportedDTypeForOp(DType::$dtype, "cpu_storage_as_slice").bt())
}
}
};
}
dummy_with_dtype!(F6E2M3, F6E2M3);
dummy_with_dtype!(F6E3M2, F6E3M2);
dummy_with_dtype!(F4, F4);
dummy_with_dtype!(F8E8M0, F8E8M0);
// Implement NumAssign traits for dummy types
macro_rules! dummy_num_assign {
($ty:ty) => {
impl std::ops::AddAssign for $ty {
fn add_assign(&mut self, _other: Self) {
panic!(
"{} is a dummy type and does not support operations",
stringify!($ty)
)
}
}
impl std::ops::SubAssign for $ty {
fn sub_assign(&mut self, _other: Self) {
panic!(
"{} is a dummy type and does not support operations",
stringify!($ty)
)
}
}
impl std::ops::MulAssign for $ty {
fn mul_assign(&mut self, _other: Self) {
panic!(View on GitHub (pinned to d5fee525bf)
Solutions
- Use a supported numeric element type (f32, f64, f16, bf16, i32, etc.) for arithmetic.
- Audit generic functions' type parameters so they are never instantiated with the dummy types.
- Convert dummy-dtype tensors to a supported dtype before reductions or element-wise ops.
- If MX formats are needed, implement real arithmetic in a candle fork rather than relying on these stubs.
Example fix
// before let mut acc = F6E2M3; acc += x; // panics // after let mut acc = 0.0f32; acc += x; // accumulate in a supported type
Defensive patterns
Strategy: type-guard
Validate before calling
fn checked_add_assign<T: WithDType + AddAssign>(x: &mut T, y: T) -> Result<()> {
if DUMMY.contains(&T::DTYPE) {
return Err(Error::UnsupportedDTypeForOp(T::DTYPE, "add_assign").bt());
}
*x += y;
Ok(())
} Type guard
fn is_real_numeric<T: WithDType>(_v: &T) -> bool {
!matches!(T::DTYPE, DType::F6E2M3 | DType::F6E3M2 | DType::F4 | DType::F8E8M0)
} Try / catch
let r = std::panic::catch_unwind(|| { let mut a = F6E2M3; a += a; });
if r.is_err() { eprintln!("arithmetic on dummy dtype is unsupported"); } Prevention
- Constrain generic numeric code to real element types, never the dummy structs
- Accumulate in f32/f64/i64 rather than experimental MX types
- Convert tensors to supported dtypes before reductions
- Add compile-time or runtime assertions excluding dummy DTYPEs in kernels
When it happens
Trigger: Using `x += y` where x has type F6E2M3/F6E3M2/F4/F8E8M0, or generic accumulation loops (sums, reductions, kernel loops bounded by Zero + AddAssign) instantiated over a dummy type.
Common situations: Generic numeric code (sums, reductions, kernel loops) instantiated over a dummy dtype instead of a real one; accidentally naming a dummy type as the element type parameter.
Related errors
- {} is a dummy type and cannot be constructed
- {} is a dummy type and cannot be converted
- {} is a dummy type and cannot be converted to scalar
- {} is a dummy type and does not support storage
- {} is a dummy type and does not support parsing
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/92fd330bf724d5d3.
Report an issue: GitHub.