huggingface/candle · error

slice-assign requires input with the same rank as there are

Error message

slice-assign requires input with the same rank as there are ranges {} <> {}

What it means

slice_assign needs exactly one range per dimension of self: the ranges slice defines the rectangular region being replaced. If the number of ranges doesn't equal self's rank, the region is underspecified, so it bails reporting self's rank and the number of ranges.

Source

Thrown at candle-core/src/tensor.rs:2877

    /// Returns a copy of `self` where the values within `ranges` have been replaced with the
    /// content of `src`.
    pub fn slice_assign<D: std::ops::RangeBounds<usize>>(
        &self,
        ranges: &[D],
        src: &Tensor,
    ) -> Result<Self> {
        let src_dims = src.dims();
        let self_dims = self.dims();
        if self_dims.len() != src_dims.len() {
            bail!(
                "slice-assign requires input with the same rank {} <> {}",
                self_dims.len(),
                src_dims.len()
            )
        }
        if self_dims.len() != ranges.len() {
            bail!(
                "slice-assign requires input with the same rank as there are ranges {} <> {}",
                self_dims.len(),
                ranges.len()
            )
        }
        let mut src = src.clone();
        let mut mask = Self::ones(src.shape(), DType::U8, src.device())?;
        for (i, range) in ranges.iter().enumerate() {
            let start_included = match range.start_bound() {
                std::ops::Bound::Unbounded => 0,
                std::ops::Bound::Included(v) => *v,
                std::ops::Bound::Excluded(v) => *v + 1,
            };
            let end_excluded = match range.end_bound() {
                std::ops::Bound::Unbounded => self_dims[i],
                std::ops::Bound::Included(v) => *v + 1,
                std::ops::Bound::Excluded(v) => *v,
            };

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Supply one range per dimension of self, using 0..dim for dims you don't want to restrict
  2. Generate ranges from self.dims() to guarantee the count matches
  3. Split the operation into narrow + assign if per-dim ranges are unwieldy

Example fix

// before
t.slice_assign(&[0..2], &src)?; // t is rank 2
// after
let d0 = t.dim(0)?;
t.slice_assign(&[0..2, 0..d0], &src)?;
Defensive patterns

Strategy: validation

Validate before calling

assert_eq!(ranges.len(), t.dims().len(), "one range per dim required");

Try / catch

let ranges = full_ranges_or(ranges, t.dims()); // fill missing dims with 0..dim
t.slice_assign(&ranges, &src)?;

Prevention

When it happens

Trigger: tensor.slice_assign(&[(0..2)?], &src) on a rank-2 tensor (1 range vs rank 2), or passing an empty ranges slice.

Common situations: Copy-pasted slice_assign calls after the tensor gained a dimension; building ranges programmatically and dropping a dim; using a 1-range pattern for a 3-D tensor.

Related errors


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