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
- Ensure every range has end > start; skip the dim (use 0..self_dim) if no restriction is needed
- Validate ranges in caller code before invoking slice_assign
- 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
- Guard computed ranges: skip assignment when start == end
- Never emit inverted ranges; clamp with .max(start)
- Add unit tests for boundary (empty) ranges
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
- slice-assign requires input with the same rank {} <> {}
- slice-assign requires input with the same rank as there are
- slice-assign: upper bound is out of range for dim {i}, {end_
- slice-assign: the range for dim {i} ({start_included}..{end_
- {} is a dummy type and cannot be constructed
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/7bed1dd6cf9db964.
Report an issue: GitHub.