{"record":{"id":"1cbdab5f56d2a6bd","repo":"tracel-ai/burn","slug":"index-out-of-bounds-for-composeddataset-index","errorCode":null,"errorMessage":"Index out of bounds for ComposedDataset: {index} >= {}","messagePattern":"Index out of bounds for ComposedDataset: (.+?) >= (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-dataset/src/transform/composed.rs","lineNumber":24,"sourceCode":"pub struct ComposedDataset<D> {\n    datasets: Vec<D>,\n}\n\nimpl<D, I, E> Dataset<I, E> for ComposedDataset<D>\nwhere\n    D: Dataset<I, E>,\n    I: Clone,\n    E: Error + Send + Sync + 'static,\n{\n    fn get(&self, index: usize) -> Result<I, E> {\n        let mut current_index = 0;\n        for dataset in self.datasets.iter() {\n            if index < dataset.len() + current_index {\n                return dataset.get(index - current_index);\n            }\n            current_index += dataset.len();\n        }\n        panic!(\n            \"Index out of bounds for ComposedDataset: {index} >= {}\",\n            self.len()\n        );\n    }\n    fn len(&self) -> usize {\n        let mut total = 0;\n        for dataset in self.datasets.iter() {\n            total += dataset.len();\n        }\n        total\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::FakeDataset;\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-dataset/src/transform/composed.rs#L6-L42","documentation":"`ComposedDataset::get` walks its child datasets, subtracting accumulated lengths, and panics if the requested `index` exceeds the total length of all composed datasets. Like the other burn datasets, out-of-range access is a panic rather than an `Err`.","triggerScenarios":"Calling `composed.get(index)` with `index >= composed.len()`; composing N datasets but iterating with bounds from one of them or from stale metadata; empty composition (`ComposedDataset::new([])`) accessed at any index.","commonSituations":"Splits composed of train/val datasets where a downstream consumer assumes a single dataset length; batch loops computing bounds from a partial list of datasets; a child dataset became empty (bad file) so the total shrank.","solutions":["Guard with `if index < composed.len()` or iterate `0..composed.len()`.","Recompute lengths from the composition itself rather than caching/splitting sizes externally.","Verify each child dataset is non-empty and loaded correctly (log child `len()`s).","Use `DataSplit`/index-based selection APIs that compute valid ranges across composed datasets."],"exampleFix":"// before\nlet total = train.len(); // wrong: composed also includes val\nlet item = composed.get(i).unwrap();\n\n// after\nlet total = composed.len();\nif i < total {\n    let item = composed.get(i)?;\n}","handlingStrategy":"validation","validationCode":"if index >= composed.len() {\n    return Err(DatasetError::InvalidArgument(format!(\"index {index} out of bounds for ComposedDataset (len={})\", composed.len())));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Take total length from `composed.len()`, never from cached or per-child sizes","Check child datasets are non-empty after construction (log each len)","Use half-open ranges `0..len` for iteration","Prefer iterators over manual index math when composing datasets"],"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"}