huggingface/candle · error

Index out of bounds for dimension with size

Error message

Index {} out of bounds for dimension {} with size {}

What it means

During ScatterGD/GatherND-style indexed evaluation, candle-onnx converts each per-dimension index to a flat offset and validates it against the data shape. Negative indices are normalized (dim_size + idx), but if the resulting index is still outside [0, dim_size) this error is thrown, naming the offending index, dimension, and size.

Solutions

  1. Clamp the indices before the op (e.g. via graph surgery or upstream clip node)
  2. Fix upstream ops producing out-of-range indices
  3. Validate indices against data shape in a preprocessing step before running the graph

Example fix

# before: idx = 10, dim size 8
# after (preprocess)
indices = np.clip(indices, -dim_size, dim_size - 1)
Defensive patterns

Strategy: validation

Validate before calling

for (dim, &idx) in indices.iter().enumerate() {
    let size = data_shape[dim] as i64;
    let n = if idx < 0 { size + idx } else { idx };
    if n < 0 || n >= size {
        return Err(format!("index {} out of bounds for dim {} (size {})", idx, dim, size));
    }
}

Type guard

fn indices_in_bounds(indices: &[i64], shape: &[usize]) -> bool {
    indices.iter().zip(shape).all(|(&i, &s)| (i as i64) >= -(s as i64) && (i as i64) < s as i64)
}

Try / catch

match eval(...) {
    Err(e) if e.contains("out of bounds for dimension") => clamp_indices_and_retry(),
    other => other,
}

Prevention

When it happens

Trigger: Evaluating a ScatterND node whose indices contain a value >= dim_size or < -dim_size for any dimension of the data tensor, e.g. index 10 into a dimension of size 8 or index -9 into size 8.

Common situations: Out-of-range indices generated by upstream ops (argmax on wrong axis, wrong padding values); integer overflow or bad position encodings in exported models.

Related errors


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

Appendix: source

Thrown at candle-onnx/src/eval.rs:2516

                let mut strides: Vec<usize> = vec![1];
                for i in (0..data_shape.len() - 1).rev() {
                    strides.push(strides.last().unwrap() * data_shape[i + 1]);
                }
                strides.reverse();

                // Process each update
                for i in 0..num_updates {
                    let index_slice = flat_indices.narrow(0, i, 1)?;
                    let indices_vec = index_slice.squeeze(0)?.to_vec1::<i64>()?;

                    // Convert multi-dimensional indices to flat index
                    let mut flat_idx: usize = 0;
                    for (dim, &idx) in indices_vec.iter().enumerate() {
                        let dim_size = data_shape[dim] as i64;
                        let norm_idx = if idx < 0 { dim_size + idx } else { idx };

                        if norm_idx < 0 || norm_idx >= dim_size {
                            bail!(
                                "Index {} out of bounds for dimension {} with size {}",
                                idx,
                                dim,
                                dim_size
                            );
                        }

                        flat_idx += (norm_idx as usize) * strides[dim];
                    }

                    // Extract current update
                    let update_slice = if update_element_shape.is_empty() {
                        flat_updates.narrow(0, i, 1)?.squeeze(0)?
                    } else {
                        flat_updates.narrow(0, i, 1)?
                    };

                    match reduction {

View on GitHub (pinned to d5fee525bf)