{"record":{"id":"d1efab700ce6e907","repo":"tracel-ai/burn","slug":"index-out-of-bounds-for-selectiondataset-i","errorCode":null,"errorMessage":"Index out of bounds for SelectionDataset: {i} >= {}","messagePattern":"Index out of bounds for SelectionDataset: (.+?) >= (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-dataset/src/transform/selection.rs","lineNumber":244,"sourceCode":"    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            })\n            .collect();\n        self.wrapped.get_many(translated)\n    }\n\n    fn len(&self) -> usize {\n        self.indices.len()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::FakeDataset;","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-dataset/src/transform/selection.rs#L226-L262","documentation":"`SelectionDataset::get_many` maps each requested position through `self.indices.get(i)`; any position missing from the indices vector triggers a panic with the position and indices length. Same family as `get` (error 97) but for batched retrieval, so one bad index in a batch aborts the whole call.","triggerScenarios":"Calling `selection.get_many(vec![...])` where any element `>= selection.len()`; batching with a fixed batch size over `total` computed from the wrapped dataset; a sampler producing positions from the wrong population size.","commonSituations":"DataLoader with batch_size that doesn't divide selection length and code appending full-size batches; shuffled index lists sampled from the wrong range; mixing `get_many` positions between two different selections.","solutions":["Clamp/filter the requested positions: `indexes.into_iter().filter(|i| *i < selection.len()).collect()` before calling.","Compute batch boundaries from `selection.len()` and truncate the final batch (`min(batch_size, len - start)`).","Ensure the sampler/batcher was built with the selection dataset (its len), not the wrapped one.","Alternatively catch mis sized batches upstream by iterating via `Dataset::batcher`/iter helpers."],"exampleFix":"// before\nlet items = selection.get_many((0..batch_size).map(|i| start + i).collect()).unwrap(); // may exceed len\n\n// after\nlet end = (start + batch_size).min(selection.len());\nlet items = selection.get_many((start..end).collect())?;","handlingStrategy":"validation","validationCode":"let positions: Vec<usize> = requested.into_iter().filter(|&i| i < selection.len()).collect();\nlet items = selection.get_many(positions)?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp batch ranges: `let end = (start + batch_size).min(selection.len())`","Build samplers/batchers from the selection dataset so sizes come from indices, not the wrapped dataset","Truncate the final partial batch instead of issuing full-size requests","Unit-test get_many with a batch crossing the end of the selection"],"tags":["dataset","index-out-of-bounds","batch","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"}