huggingface/candle · error

Expand: incompatible shapes for broadcast, {:?} and {:?}

Error message

Expand: incompatible shapes for broadcast, {:?} and {:?}

What it means

broadcast_shape implements NumPy-style broadcasting used by the Expand operator: dimensions must be equal, or one of them must be 1. When two aligned dimensions differ and neither is 1, the shapes cannot be broadcast and this error fires, echoing both shapes.

Source

Thrown at candle-onnx/src/eval.rs:2592

            None => bail!("cannot find output {}", output.name),
            Some(value) => Ok((output.name.clone(), value)),
        })
        .collect()
}

fn broadcast_shape(shape_a: &[usize], shape_b: &[usize]) -> Result<Vec<usize>> {
    let (longest, shortest) = if shape_a.len() > shape_b.len() {
        (shape_a, shape_b)
    } else {
        (shape_b, shape_a)
    };
    let diff = longest.len() - shortest.len();
    let mut target_shape = longest[0..diff].to_vec();
    for (dim1, dim2) in longest[diff..].iter().zip(shortest.iter()) {
        if *dim1 == *dim2 || *dim2 == 1 || *dim1 == 1 {
            target_shape.push(usize::max(*dim1, *dim2));
        } else {
            bail!(
                "Expand: incompatible shapes for broadcast, {:?} and {:?}",
                shape_a,
                shape_b
            );
        }
    }
    Ok(target_shape)
}

fn broadcast_shape_from_many(shapes: &[&[usize]]) -> Result<Vec<usize>> {
    if shapes.is_empty() {
        return Ok(Vec::new());
    }
    let mut shape_out = shapes[0].to_vec();
    for shape in shapes[1..].iter() {
        shape_out = broadcast_shape(&shape_out, shape)?;
    }
    Ok(shape_out)

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Correct the Expand `shape` input so each dim equals the input dim or is 1
  2. Fix upstream ops producing the wrong target shape
  3. Validate shape compatibility (dims equal or 1 after left-alignment) before running the graph

Example fix

# before
Expand: input [3,1], shape [4,4]  -> error
# after
Expand: input [3,1], shape [3,4]  # dims align (3==3, 1 broadcasts to 4)
Defensive patterns

Strategy: validation

Validate before calling

fn can_broadcast(a: &[usize], b: &[usize]) -> bool {
    let (long, short) = if a.len() >= b.len() { (a, b) } else { (b, a) };
    let d = long.len() - short.len();
    long[d..].iter().zip(short).all(|(&x, &y)| x == y || x == 1 || y == 1)
}

Type guard

fn expand_target_ok(input: &Tensor, target: &[usize]) -> bool {
    can_broadcast(input.dims(), target)
}

Try / catch

match eval(...) {
    Err(e) if e.contains("incompatible shapes for broadcast") => eprintln!("Expand shape incompatible with input"),
    other => other,
}

Prevention

When it happens

Trigger: Calling Expand with a target shape incompatible with the input shape, e.g. expanding [3,1] to [4,4] (dim 3 vs 4), or broadcast_shape_from_many receiving mutually incompatible shapes.

Common situations: Models where the expand `shape` input is computed dynamically and ends up wrong; exporter miscalculations; hand-written shapes with typos; rank mismatches beyond left-padding rules.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/60df901fbc81732a. Report an issue: GitHub.