{"record":{"id":"fd951cc680648636","repo":"tracel-ai/burn","slug":"index-out-of-bounds-for-selectiondataset-index","errorCode":null,"errorMessage":"Index out of bounds for SelectionDataset: {index} >= {}","messagePattern":"Index out of bounds for SelectionDataset: (.+?) >= (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-dataset/src/transform/selection.rs","lineNumber":231,"sourceCode":"\n            let dataset = self.slice(start, end);\n\n            current += batch_size;\n            datasets.push(dataset);\n        }\n\n        datasets\n    }\n}\n\nimpl<D, I> Dataset<I> for SelectionDataset<D, I>\nwhere\n    D: Dataset<I>,\n    I: Clone + Send + Sync,\n{\n    fn get(&self, index: usize) -> Result<I, DatasetError> {\n        let Some(&index) = self.indices.get(index) else {\n            panic!(\n                \"Index out of bounds for SelectionDataset: {index} >= {}\",\n                self.indices.len()\n            );\n        };\n        self.wrapped.get(index)\n    }\n\n    fn get_many(&self, indexes: Vec<usize>) -> Result<Vec<I>, DatasetError> {\n        let translated: Vec<usize> = indexes\n            .into_iter()\n            .map(|i| {\n                self.indices.get(i).copied().unwrap_or_else(|| {\n                    panic!(\n                        \"Index out of bounds for SelectionDataset: {i} >= {}\",\n                        self.indices.len()\n                    )\n                })\n            })","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-dataset/src/transform/selection.rs#L213-L249","documentation":"`SelectionDataset`'s `Dataset::get` first looks up `self.indices[index]` to translate the selection position into a wrapped-dataset index; if the position is not present in the indices vector (i.e. `index >= indices.len()`), it panics. Note the bound checked is the length of the indices list, not the wrapped dataset.","triggerScenarios":"Calling `selection.get(position)` with `position >= selection.len()` (== `self.indices.len()`); iterating past the selection length; batch code using the wrapped dataset's length instead of the selection's length.","commonSituations":"Using `wrapped.len()` for loop bounds while the selection is a subset (e.g. a validation subset of train); stale cached lengths after reshuffling; off-by-one `0..=len` loops.","solutions":["Bound loops by `selection.len()`, not the wrapped dataset's length.","Guard each access: `if index < selection.len() { selection.get(index) }`.","Use `selection.iter()` / sampler APIs that respect the selection size.","Verify the selection was constructed with the intended index list (log its len)."],"exampleFix":"// before\nfor i in 0..wrapped.len() {\n    let item = selection.get(i).unwrap(); // panics once i >= selection.len()\n}\n\n// after\nfor i in 0..selection.len() {\n    let item = selection.get(i)?;\n}","handlingStrategy":"validation","validationCode":"if index < selection.len() {\n    let item = selection.get(index)?;\n} else {\n    // handle out-of-range position","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Bound iteration by `selection.len()` (the indices length), not the wrapped dataset's length","Prefer `selection.iter()` or DataLoader-driven batching over manual indexing","Don't reuse raw positions across different SelectionDatasets","Add a debug assert `index < selection.len()` in hot loops during development"],"tags":["dataset","index-out-of-bounds","burn","rust"],"backgroundTag":"dataset-index-out-of-bounds","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}