huggingface/candle · error

slice-assign requires input with the same rank {} <> {}

Error message

slice-assign requires input with the same rank {} <> {}

What it means

Tensor::slice_assign writes a source tensor into a rectangular region of self defined by ranges. Both tensors must have the same number of dimensions, because each dim of src is matched pairwise with a range and a dim of self. When ranks differ, the method bails reporting self's rank and src's rank.

Source

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

        } else {
            let last = rank - 1;
            let t = self.transpose(dim, last)?;
            let t = t.broadcast_matmul(&triu)?;
            t.transpose(dim, last)
        }
    }

    /// 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,

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Unsqueeze or reshape src so its rank equals self's rank
  2. Verify both shapes with t.dims().len() == src.dims().len() before the call
  3. Use tensor.narrow/cat to build the result if a full reassignment is simpler

Example fix

// before
t.slice_assign(&(0..2, 1..3), &src)?; // src is rank 1
// after
let src = src.unsqueeze(0)?; // now rank 2
t.slice_assign(&(0..2, 1..3), &src)?;
Defensive patterns

Strategy: validation

Validate before calling

if src.dims().len() != t.dims().len() {
    panic!("rank mismatch: {} vs {}", t.dims().len(), src.dims().len());
}

Try / catch

let src = if src.dims().len() != t.dims().len() { src.unsqueeze(0)? } else { src };
t.slice_assign(ranges, &src)?;

Prevention

When it happens

Trigger: tensor.slice_assign(&[(0..2)?], &src) where src.rank() != self.rank(), e.g. assigning a 1-D vector into a 2-D tensor region.

Common situations: Forgetting to unsqueeze src before slice-assigning into a batched tensor; passing a scalar/1-D row where a rank-N slice was required; shape refactors after adding a batch dimension.

Related errors


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