huggingface/candle · error

slice-assign: empty range for dim {i}, {start_included} {end

Error message

slice-assign: empty range for dim {i}, {start_included} {end_excluded}

What it means

For each dimension, slice_assign resolves the range's start and end bounds and requires a non-empty interval: end_excluded must be strictly greater than start_included. An empty range (e.g. 3..3 or 5..2) defines a zero-width region that cannot be assigned, so it bails naming the dim and the resolved bounds.

Source

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

                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,
            };
            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)
    }

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Ensure every range has end > start; skip the dim (use 0..self_dim) if no restriction is needed
  2. Validate ranges in caller code before invoking slice_assign
  3. Check upstream computations that produce zero-length spans

Example fix

// before
t.slice_assign(&[3..3, 0..4], &src)?;
// after
if start < end {
    t.slice_assign(&[start..end, 0..4], &src)?;
}
Defensive patterns

Strategy: validation

Validate before calling

fn valid_range(r: &std::ops::Range<usize>) -> bool { r.start < r.end }
assert!(ranges.iter().all(valid_range));

Try / catch

if start >= end { return Ok(t.clone()); } // or skip dim
t.slice_assign(&[start..end, 0..d1], &src)?;

Prevention

When it happens

Trigger: Passing Range { start: 3, end: 3 } or an inverted range like 5..2 for some dim; a range built from computed start/end that collapsed to empty.

Common situations: Computing ranges from dynamic sizes where end == start after clamping; using an exclusive bound equal to the start; loop-generated ranges where a size was 0.

Related errors


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