tracel-ai/burn · error

Broadcast arguments must be positive or -1! Got {}

Error message

Broadcast arguments must be positive or -1! Got {}

What it means

In BroadcastArgs::into_shape, each broadcast dimension may be a positive size or -1 (meaning 'keep this dimension unchanged'); 0 or anything less than -1 is invalid. Burn panics with the offending value when iterating the arguments right-to-left and finding primitive < -1 or primitive == 0. A zero-sized broadcast dim is almost always a computed value that collapsed (e.g. an empty batch or a division yielding 0).

Source

Thrown at crates/burn-tensor/src/tensor/api/base.rs:3389

impl<const D1: usize, const D2: usize, E: AsIndex> BroadcastArgs<D1, D2> for [E; D2] {
    // Passing -1 as the size for a dimension means not changing the size of that dimension.
    fn into_shape(self, shape: &Shape) -> Shape {
        if self.len() < shape.num_dims() {
            panic!(
                "Broadcast arguments must be greater than the number of dimensions! got {}, need at least {}",
                self.len(),
                shape.num_dims()
            );
        }

        // Zip the two shapes in reverse order and replace -1 with the actual dimension value.
        let new_shape: Vec<_> = self
            .iter()
            .rev()
            .map(|x| {
                let primitive = x.as_index();
                if primitive < -1 || primitive == 0 {
                    panic!(
                        "Broadcast arguments must be positive or -1! Got {}",
                        primitive
                    );
                }
                primitive
            })
            .zip(shape.iter().rev().chain(repeat(&0)).take(self.len())) // Pad the original shape with 0s
            .map(|(x, &y)| if x == -1 { y } else { x as usize })
            .collect::<Vec<_>>()
            .into_iter()
            .rev()
            .collect();

        if new_shape.contains(&0) {
            panic!(
                "Cannot substitute -1 for a non-existing dimension! Got {:?}",
                new_shape
            );

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Validate dimension sizes before calling: reject 0 and values < -1, mapping 'keep' semantics to -1 explicitly
  2. Fix the computation producing the dim size (guard against empty inputs, clamp to >= 1 where a real dim is required)
  3. Replace the invalid literal with -1 if the intent was to keep the existing dimension
  4. Clamp/derive the target dims from tensor.dims() instead of hand-computed values

Example fix

// before
let y = x.reshape([0, -1]); // 0 is invalid -> panic
// after
let y = x.reshape([-1, -1]); // -1 keeps the existing dim, or use a positive size
Defensive patterns

Strategy: validation

Validate before calling

// Reject invalid broadcast dims before calling the API
fn valid_dim(d: i64) -> bool { d == -1 || d > 0 }
assert!(args.iter().all(|d| valid_dim(d.as_index())), "dims must be > 0 or exactly -1");

Try / catch

// Panic API; sanitize inputs first:
let args: Vec<_> = args.into_iter().map(|d| if d == 0 { 1 } else { d }).collect(); // example sanitization

Prevention

When it happens

Trigger: Passing 0 as a dimension size in a reshape/broadcast arg array; passing -2 or lower (typo or sign error); computing a dim size arithmetically and getting 0 (e.g. len // something); using i64/i32 indices where a negative sentinel other than -1 was produced.

Common situations: Dynamic batch sizes hitting 0 on an empty batch; porting numpy semantics where 0 is legal but -1-only semantics apply in Burn; off-by-one or negation bugs in generated shape code.

Related errors


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