{"record":{"id":"2b39e636869a6a3c","repo":"nautechsystems/nautilus_trader","slug":"chunk-should-have-at-least-one-element-to-encode","errorCode":null,"errorMessage":"Chunk should have at least one element to encode","messagePattern":"Chunk should have at least one element to encode","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/databento/src/arrow/statistics.rs","lineNumber":143,"sourceCode":"                Arc::new(ts_event_builder.finish()),\n                Arc::new(ts_recv_builder.finish()),\n                Arc::new(ts_init_builder.finish()),\n            ],\n        )\n    }\n\n    fn metadata(&self) -> HashMap<String, String> {\n        Self::get_metadata(\n            &self.instrument_id,\n            self.price.map_or(FIXED_PRECISION, |p| p.precision),\n            self.quantity.map_or(FIXED_PRECISION, |q| q.precision),\n        )\n    }\n\n    fn chunk_metadata(chunk: &[Self]) -> HashMap<String, String> {\n        let first = chunk\n            .first()\n            .expect(\"Chunk should have at least one element to encode\");\n\n        let price_precision = chunk\n            .iter()\n            .find_map(|s| s.price.map(|p| p.precision))\n            .unwrap_or(FIXED_PRECISION);\n        let size_precision = chunk\n            .iter()\n            .find_map(|s| s.quantity.map(|q| q.precision))\n            .unwrap_or(FIXED_PRECISION);\n\n        Self::get_metadata(&first.instrument_id, price_precision, size_precision)\n    }\n}\n\nimpl DecodeDataFromRecordBatch for DatabentoStatistics {\n    fn decode_data_batch(\n        metadata: &HashMap<String, String>,\n        record_batch: RecordBatch,","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/databento/src/arrow/statistics.rs#L125-L161","documentation":"chunk_metadata is part of the Arrow encoding path for Databento records: it inspects the first element of a chunk to derive metadata (price/size precision) for the record batch. The expect asserts the chunk is non-empty; encoding an empty slice is unsupported because there is no record to derive precision metadata from, so it panics instead of producing an empty batch with metadata.","triggerScenarios":"Calling the encode/chunking API with an empty slice of statistics records (chunk.len() == 0), typically after filtering a batch to nothing or miscomputing chunk boundaries so the last chunk is empty.","commonSituations":"Upstream data source returned no rows for a subscription window; a filtering step removed all records; off-by-one chunking produces trailing empty chunks fed to the encoder.","solutions":["Guard the caller: skip encoding (or emit an empty RecordBatch without metadata) when the chunk is empty.","Fix chunk-boundary computation so empty chunks are never produced.","Ensure the data source query/subscription actually yields rows before invoking the encoder."],"exampleFix":"// before\nencode(chunk); // panics when chunk.is_empty()\n// after\nif !chunk.is_empty() {\n    encode(chunk);\n} else {\n    // skip or emit empty batch without metadata\n}","handlingStrategy":"validation","validationCode":"if chunk.is_empty() {\n    return Ok(()); // or emit an empty batch without metadata\n}\nencode_chunk(chunk);","typeGuard":null,"tryCatchPattern":"// Avoid panics upstream by validating before the encoder; catch only as a safety net:\nstd::panic::catch_unwind(|| encode_chunk(chunk)).map_err(|_| anyhow!(\"empty chunk encoded\"))","preventionTips":["Check chunk emptiness before encoding.","Fix chunking logic so empty trailing chunks are never produced.","Verify the data source yields rows before entering the encode path."],"tags":["rust","arrow","panic","databento","empty-input"],"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"}