{"record":{"id":"5eba8e4dce152a8e","repo":"nautechsystems/nautilus_trader","slug":"missing-metadata-cache-for-dynamic-instrument-id","errorCode":null,"errorMessage":"missing metadata cache for dynamic instrument id","messagePattern":"missing metadata cache for dynamic instrument id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/databento/src/loader.rs","lineNumber":960,"sourceCode":"                    Err(e) => return Some(Err(e)),\n                }\n            }\n        }))\n    }\n\n    fn resolve_record_instrument_id(\n        &self,\n        record: &dbn::RecordRef,\n        instrument_id: Option<InstrumentId>,\n        metadata_cache: &mut Option<MetadataCache>,\n    ) -> anyhow::Result<InstrumentId> {\n        if let Some(instrument_id) = instrument_id {\n            return Ok(instrument_id);\n        }\n\n        let metadata_cache = metadata_cache\n            .as_mut()\n            .ok_or_else(|| anyhow::anyhow!(\"missing metadata cache for dynamic instrument id\"))?;\n\n        decode_nautilus_instrument_id(\n            record,\n            metadata_cache,\n            &self.publisher_venue_map,\n            &self.symbol_venue_map,\n        )\n    }\n\n    fn resolve_stream_price_precision(\n        &self,\n        instrument_id: &InstrumentId,\n        fixed_instrument_id: bool,\n        fixed_price_precision: &mut Option<u8>,\n    ) -> anyhow::Result<u8> {\n        if let Some(precision) = *fixed_price_precision {\n            return Ok(precision);\n        }","sourceCodeStart":942,"sourceCodeEnd":978,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/databento/src/loader.rs#L942-L978","documentation":"Databento's DBN decoder can map some record instrument IDs directly, but dynamic (numeric) instrument IDs require a metadata cache holding the symbology (symbol maps) to be resolved to a Nautilus InstrumentId. This error is thrown in resolve_record_instrument_id when a dynamic instrument ID is encountered but the caller passed a None metadata cache. It is a defensive invariant: loading data with dynamic IDs without metadata is impossible to resolve.","triggerScenarios":"Calling read_records / read_order_book_deltas / load_status_records / read_imbalance_records / read_statistics_records on a dataset whose records use dynamic instrument IDs (e.g. GLBX.MDP3 raw numeric IDs) while passing None for metadata_cache, typically when the loader was not built with symbology metadata (no `databento::Metadata` from the batch/download call).","commonSituations":"Reading historical data files without their accompanying metadata; constructing a DatabentoDataLoader manually and skipping set_metadata_cache; streaming records from a source that does not provide DBN metadata; requesting data where instrument_id was not fixed via the `symbols` parameter so records carry dynamic IDs.","solutions":["Pass a metadata cache to the loader: obtain `databento::Metadata` from the historical client (get_range/get_batch call) and attach it via the loader's metadata_cache setter before reading.","Request data for explicit symbols so records resolve to non-dynamic instrument IDs and the cache is not needed.","If reading pre-downloaded DBN files, load the matching metadata file first and register it with the loader.","Verify the dataset does not use dynamic instrument IDs for the record types you decode (GLBX.MDP3 definitions/status typically do)."],"exampleFix":"// before\nloader.read_order_book_deltas(&mut handler, None)?;\n\n// after\nlet metadata = client.get_range(...).await?.metadata;\nloader.set_metadata_cache(metadata);\nloader.read_order_book_deltas(&mut handler, None)?;","handlingStrategy":"validation","validationCode":"// Rust\nanyhow::ensure!(\n    loader.metadata_cache().is_some(),\n    \"metadata cache required for datasets with dynamic instrument ids\"\n);","typeGuard":null,"tryCatchPattern":"match loader.read_order_book_deltas(&mut handler, None) {\n    Ok(_) => {},\n    Err(e) if e.to_string().contains(\"missing metadata cache\") => attach_metadata_and_retry(loader)?,\n    Err(e) => return Err(e),\n}","preventionTips":["Always attach the Metadata from the same get_range/get_batch call that produced the data","When loading pre-downloaded DBN files, load the corresponding metadata file first","Prefer explicit symbols in requests to avoid dynamic instrument IDs","Add an assertion in the load pipeline that the cache is present before reading"],"tags":["databento","rust","symbology","missing-metadata"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}