tracel-ai/burn · error

index {raw} out of bounds for dimension of size {dim_size}

Error message

index {raw} out of bounds for dimension of size {dim_size}

What it means

index_oob panics when an index read from the indices tensor is negative or >= the size of the dimension being indexed. checked_index routes every invalid index here so gather/scatter/select ops fail with a clear message instead of reading out-of-bounds memory.

Source

Thrown at crates/burn-flex/src/ops/gather_scatter.rs:141

                })
                .collect(),
        ),
        DType::U16 => Cow::Owned(
            tensor
                .storage::<u16>()
                .iter()
                .map(|&v| v as isize)
                .collect(),
        ),
        DType::U8 => Cow::Owned(tensor.storage::<u8>().iter().map(|&v| v as isize).collect()),
        other => panic!("read_indices: unsupported index dtype {:?}", other),
    }
}

#[cold]
#[inline(never)]
fn index_oob(raw: isize, dim_size: usize) -> ! {
    panic!("index {raw} out of bounds for dimension of size {dim_size}");
}

/// Validate an index is non-negative and within bounds, panicking with a clear message otherwise.
#[inline(always)]
fn checked_index(raw: isize, dim_size: usize) -> usize {
    if raw < 0 || raw as usize >= dim_size {
        index_oob(raw, dim_size);
    }
    raw as usize
}

/// Gather values from tensor along a dimension using indices.
///
/// For a 2D tensor with dim=1:
/// output[i, j] = tensor[i, indices[i, j]]
///
/// The output has the same shape as indices.
pub fn gather<E: Element + Pod + Default + Copy + Send + Sync>(

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Validate/clamp indices to [0, dim_size) before the op (tensor.clamp or explicit bounds check)
  2. Check that the indices tensor was built for the current tensor shape, not an older one
  3. Replace padding sentinel values (-1) with a valid index or use a masked scatter
  4. Log the failing raw index and dim_size from the panic message to find the producer of the bad index

Example fix

// before: -1 used as 'none' sentinel
let out = tensor.gather(0, idx); // panic: index -1 out of bounds for dimension of size 10
// after: clamp sentinels into range and mask afterwards
let safe_idx = idx.clamp(0i64, (dim_size - 1) as i64);
let gathered = tensor.gather(0, safe_idx);
let out = gathered.mask_fill(idx.lower_equal(-1i64), 0f32);
Defensive patterns

Strategy: validation

Validate before calling

// validate all indices are within [0, dim_size) before the op
let in_range = indices
    .clone()
    .greater_equal_elem(0i64)
    .bool_and(indices.clone().lower_equal_elem((dim_size - 1) as i64));
assert!(in_range.all().into_scalar());

Type guard

fn indices_in_range(idx: &Tensor<B, D, Int>, dim_size: usize) -> bool {
    let min_ok = idx.clone().greater_equal_elem(0i64).all().into_scalar();
    let max_ok = idx.clone().lower_equal_elem((dim_size - 1) as i64).all().into_scalar();
    min_ok && max_ok
}

Prevention

When it happens

Trigger: Any of gather, scatter_update, select, select_update, scatter_nd, gather_nd receiving an indices tensor containing a negative value or a value >= dim_size for the target dimension.

Common situations: Off-by-one errors when building index tensors, negative padding values used as indices, indices computed for a differently-shaped tensor, model weights/exported graphs referencing stale dimensions, or clamping forgotten after arithmetic.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/b5d8b2f3e58f50cd. Report an issue: GitHub.