tracel-ai/burn · error

read_indices: u32 index {v} out of isize range

Error message

read_indices: u32 index {v} out of isize range

What it means

read_indices converts U32 index tensors to isize; a u32 value above isize::MAX (possible only on 32-bit targets) cannot be represented, and the library panics instead of producing a wrapped negative index. This protects gather/scatter addressing from silent truncation.

Source

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

                })
                .collect(),
        ),
        #[cfg(target_pointer_width = "64")]
        DType::U32 => Cow::Owned(
            tensor
                .storage::<u32>()
                .iter()
                .map(|&v| v as isize)
                .collect(),
        ),
        #[cfg(target_pointer_width = "32")]
        DType::U32 => Cow::Owned(
            tensor
                .storage::<u32>()
                .iter()
                .map(|&v| {
                    isize::try_from(v).unwrap_or_else(|_| {
                        panic!("read_indices: u32 index {v} out of isize range")
                    })
                })
                .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)]

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Keep tensors and index arithmetic small enough that u32 indices stay below 2^31 on 32-bit targets
  2. Validate indices are < dim_size before the op
  3. Compile for a 64-bit target where u32 always fits isize
  4. Use u8/u16 index dtypes when dimension sizes allow, avoiding the conversion path entirely

Example fix

// before: u32 flat indices over a huge flattened tensor on wasm32
let idx = flat_positions.cast::<u32>();
let out = tensor.gather(0, idx);
// after: chunk so indices stay within 32-bit range, or build for wasm64
assert!(flat_positions.max_val::<u32>() < isize::MAX as u32);
let out = tensor.gather(0, flat_positions.cast::<u32>());
Defensive patterns

Strategy: validation

Validate before calling

// before calling gather/scatter with a u32 indices tensor (esp. wasm32/armv7)
let max_idx = indices.max_val::<u32>();
assert!((max_idx as u64) < isize::MAX as u64);
assert!((max_idx as u64) < dim_size as u64);

Type guard

fn fits_isize_u32(v: u32) -> bool { (v as u64) < isize::MAX as u64 }

Prevention

When it happens

Trigger: gather, scatter_update, select, select_update, scatter_nd, or gather_nd with a U32 indices tensor whose value exceeds isize::MAX — realistically only on 32-bit platforms (wasm32, armv7) with u32 indices >= 2^31.

Common situations: Deploying to wasm32 with large tensors whose flattened indices exceed 2^31, garbage u32 index data, or code that computes indices with u32 arithmetic overflow.

Related errors


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