{"record":{"id":"e0595bf2dae1f5cf","repo":"nautechsystems/nautilus_trader","slug":"invalid-levels-levels-must-be-5-or-25","errorCode":null,"errorMessage":"Invalid levels: {levels}. Must be 5 or 25.","messagePattern":"Invalid levels: (.+?)\\. Must be 5 or 25\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/tardis/src/csv/stream.rs","lineNumber":1245,"sourceCode":"    records_processed: usize,\n}\n\nimpl Depth10StreamIterator {\n    /// Creates a new [`Depth10StreamIterator`].\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the file cannot be opened or read, or if `levels` is not 5 or 25.\n    pub(crate) fn new<P: AsRef<Path>>(\n        filepath: P,\n        chunk_size: usize,\n        levels: u8,\n        price_precision: Option<u8>,\n        size_precision: Option<u8>,\n        instrument_id: Option<InstrumentId>,\n        limit: Option<usize>,\n    ) -> anyhow::Result<Self> {\n        anyhow::ensure!(\n            levels == 5 || levels == 25,\n            \"Invalid levels: {levels}. Must be 5 or 25.\"\n        );\n\n        let (final_price_precision, final_size_precision) =\n            if let (Some(price_prec), Some(size_prec)) = (price_precision, size_precision) {\n                // Both precisions provided, use them directly\n                (price_prec, size_prec)\n            } else {\n                // One or both precisions missing, detect only the missing ones\n                let mut reader = create_csv_reader(&filepath)?;\n                let mut record = StringRecord::new();\n                let (detected_price, detected_size) =\n                    Self::detect_precision_from_sample(&mut reader, &mut record, 10_000);\n                (\n                    price_precision.unwrap_or(detected_price),\n                    size_precision.unwrap_or(detected_size),\n                )","sourceCodeStart":1227,"sourceCodeEnd":1263,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/tardis/src/csv/stream.rs#L1227-L1263","documentation":"Depth10StreamIterator::new validates the levels parameter with anyhow::ensure! and returns this error when levels is neither 5 nor 25. The Tardis CSV order-book snapshot data only comes in depth-5 (snapshot5) and depth-25 (snapshot25) record variants, so any other depth is rejected at construction time.","triggerScenarios":"Calling stream_order_book_depth10 (or stream_order_book_depth at 5/25 dispatch) with levels values such as 10, 0, 1, or 20; passing a user-config value like a book depth setting straight through without mapping to 5/25.","commonSituations":"Configuring a depth of 10 (confusing OrderBookDepth10 storage with the source levels); wiring an arbitrary config integer into the levels argument; copying an example and editing the levels value.","solutions":["Pass levels = 5 for Tardis derivative_ticker snapshot5 files or levels = 25 for snapshot25 files.","Map your application's configured depth to the nearest supported value (5 or 25) before calling the streamer.","Note that output is still OrderBookDepth10 (10 stored levels); a source levels of 5 yields only the first 5 populated levels.","Validate the config value at startup with a clear check like levels == 5 || levels == 25."],"exampleFix":"// before\nlet it = stream_order_book_depth10(\"snapshots.csv\", 10_000, 10, None, None, None, None)?;\n// after: levels must be 5 or 25 (output type stays OrderBookDepth10)\nlet it = stream_order_book_depth10(\"snapshots.csv\", 10_000, 25, None, None, None, None)?;","handlingStrategy":"validation","validationCode":"fn validate_levels(levels: u8) -> anyhow::Result<()> {\n    anyhow::ensure!(levels == 5 || levels == 25, \"levels must be 5 or 25, got {levels}\");\n    Ok(())\n}\n// call before constructing the stream\nvalidate_levels(cfg.depth)?;","typeGuard":"fn is_supported_levels(levels: u8) -> bool { levels == 5 || levels == 25 }","tryCatchPattern":"if !is_supported_levels(cfg.depth) {\n    return Err(anyhow::anyhow!(\"config depth {} unsupported; use 5 or 25\", cfg.depth));\n}\nlet it = stream_order_book_depth10(path, chunk, cfg.depth, None, None, None, None)?;","preventionTips":["Remember only 5 and 25 are valid levels for Tardis snapshot data.","Do not confuse OrderBookDepth10 (output type) with the source depth.","Validate config values at startup.","Map arbitrary configured depths to the nearest supported level explicitly."],"tags":["validation","argument","tardis","orderbook"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}