huggingface/candle · error

slice-assign: upper bound is out of range for dim {i}, {end_

Error message

slice-assign: upper bound is out of range for dim {i}, {end_excluded} {}

What it means

slice_assign resolves each range's end bound (Unbounded -> dim size, Included(v) -> v+1, Excluded(v) -> v) and requires the resulting end_excluded to fit within self's dimension size. If end_excluded exceeds that size, the target region extends past the tensor and the method bails reporting the bound and the dim size.

Source

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

        }
        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,
            };
            if end_excluded <= start_included {
                bail!("slice-assign: empty range for dim {i}, {start_included} {end_excluded}")
            }
            if self_dims[i] < end_excluded {
                bail!(
                    "slice-assign: upper bound is out of range for dim {i}, {end_excluded} {}",
                    self_dims[i]
                )
            }
            if end_excluded - start_included != src_dims[i] {
                bail!(
                    "slice-assign: the range for dim {i} ({start_included}..{end_excluded}) does not match the size of src {}", src_dims[i]
                )
            }
            src = src.pad_with_zeros(i, start_included, self_dims[i] - end_excluded)?;
            mask = mask.pad_with_zeros(i, start_included, self_dims[i] - end_excluded)?
        }
        mask.where_cond(/* on_true= */ &src, /* on_false= */ self)
    }

    /// Returns log(sum(exp(tensor), dim)).
    pub fn log_sum_exp<D: Dims>(&self, sum_dims: D) -> Result<Self> {
        let sum_dims = sum_dims.to_indexes(self.shape(), "log-sum-exp")?;

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Clamp range ends to self.dims()[i] before calling
  2. Use .. (Unbounded) for dims where you want the full extent
  3. Recompute bounds from the tensor's current dims instead of constants

Example fix

// before
t.slice_assign(&[0..10, 0..4], &src)?; // dim0 size 8
// after
let end = t.dim(0)?.min(10);
t.slice_assign(&[0..end, 0..4], &src)?;
Defensive patterns

Strategy: validation

Validate before calling

let d0 = t.dim(0)?;
let range = 0..end.min(d0); // clamp before calling
assert!(range.end <= d0);

Try / catch

let end = end.min(t.dim(i)?);
t.slice_assign(&[start..end, 0..d1], &src)?;

Prevention

When it happens

Trigger: Passing 0..10 to a dim of size 8, or Bound::Included(7) on a dim of size 8 (resolves to end 9 > 8).

Common situations: Hardcoded slice bounds from another tensor's shape; forgetting Included(v) means 'v is inside' so end becomes v+1; shape changed after a resize/reshape and bounds went stale.

Related errors


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