{"record":{"id":"a92c95d554abe59b","repo":"nautechsystems/nautilus_trader","slug":"data-was-empty","errorCode":null,"errorMessage":"data was empty","messagePattern":"data was empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/engine.rs","lineNumber":464,"sourceCode":"            validate,\n        )?;\n        self.data_iterator.add_data_batch(&stream_name, data, true);\n        self.sorted = sort;\n\n        Ok(())\n    }\n\n    fn register_added_data<'a>(\n        &mut self,\n        items: impl Iterator<Item = DataRef<'a>> + Clone,\n        client_id: Option<ClientId>,\n        validate: bool,\n    ) -> anyhow::Result<String> {\n        #[cfg(not(feature = \"defi\"))]\n        let _ = client_id;\n\n        let Some(first) = items.clone().next() else {\n            anyhow::bail!(\"data was empty\");\n        };\n\n        if validate {\n            // Validate against the first element only and assume the batch is\n            // homogeneous (documented contract on add_data).\n            #[cfg(feature = \"defi\")]\n            let first_is_defi = matches!(first, DataRef::Defi(_));\n            #[cfg(not(feature = \"defi\"))]\n            let first_is_defi = false;\n\n            if !first_is_defi && !matches!(first, DataRef::Custom(_)) {\n                let first_instrument_id = first.instrument_id();\n                anyhow::ensure!(\n                    self.kernel\n                        .cache\n                        .borrow()\n                        .instrument(&first_instrument_id)\n                        .is_some(),","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/engine.rs#L446-L482","documentation":"register_added_data requires at least one data item to derive the client id and (when validate=true) the type to validate against. An empty iterator provides no first element, so the engine bails rather than silently registering nothing.","triggerScenarios":"Calling add_data(vec![]) or add_data_batch with an empty collection, or a filtered/empty iterator passed as `items`.","commonSituations":"Building data lists conditionally (e.g. loading bars from a directory with no matching files); filter returning empty; API response parsed into zero items.","solutions":["Check the data collection is non-empty before calling add_data/add_data_batch","Log or assert on the data-loading step to catch loaders that return zero rows","Guard the call site: skip registration or surface a clearer error when the list is empty"],"exampleFix":"// before\nengine.add_data_batch(data)?;\n// after\nanyhow::ensure!(!data.is_empty(), \"no data loaded to add\");\nengine.add_data_batch(data)?;","handlingStrategy":"validation","validationCode":"anyhow::ensure!(!data.is_empty(), \"add_data called with empty data\");\nengine.add_data_batch(data)?;","typeGuard":null,"tryCatchPattern":"match engine.add_data(data) {\n    Err(e) if e.to_string() == \"data was empty\" => {\n        eprintln!(\"data loader returned nothing; check source files/filters\");\n    }\n    other => other?,\n}","preventionTips":["Check loaders return at least one record before registration","Assert data non-empty in test fixtures","Log data counts at load time to catch silent empty filters"],"tags":["backtest","empty-input","data-loading"],"backgroundTag":"empty-required-field","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}