{"record":{"id":"96ae69b0f96d6adb","repo":"nautechsystems/nautilus_trader","slug":"custom-data-request-requires-instrument-id-metad","errorCode":null,"errorMessage":"custom data request requires `instrument_id` metadata","messagePattern":"custom data request requires `instrument_id` metadata","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/data.rs","lineNumber":476,"sourceCode":"            return Ok(None);\n        };\n\n        let instrument_id = InstrumentId::from_str(raw_instrument_id)\n            .with_context(|| format!(\"invalid instrument_id metadata `{raw_instrument_id}`\"))?;\n\n        Ok(Some(instrument_id))\n    }\n\n    fn required_instrument_id_metadata(data_type: &DataType) -> anyhow::Result<InstrumentId> {\n        let Some(raw_instrument_id) = data_type\n            .metadata()\n            .as_ref()\n            .and_then(|m| m.get(\"instrument_id\"))\n            .and_then(|v| v.as_str())\n            .map(str::trim)\n            .filter(|value| !value.is_empty())\n        else {\n            anyhow::bail!(\"custom data request requires `instrument_id` metadata\");\n        };\n\n        InstrumentId::from_str(raw_instrument_id)\n            .with_context(|| format!(\"invalid instrument_id metadata `{raw_instrument_id}`\"))\n    }\n\n    fn required_period_metadata(data_type: &DataType) -> anyhow::Result<String> {\n        let Some(period) = data_type\n            .metadata()\n            .as_ref()\n            .and_then(|m| m.get(\"period\"))\n            .and_then(|v| v.as_str())\n            .map(str::trim)\n            .filter(|value| !value.is_empty())\n        else {\n            anyhow::bail!(\"historical open interest request requires `period` metadata\");\n        };\n","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/futures/data.rs#L458-L494","documentation":"A Binance Futures custom data request (DataCmd) must include `instrument_id` in its metadata map, so the adapter can resolve which instrument the request targets. `required_instrument_id_metadata` bails when the metadata is absent, empty, or whitespace.","triggerScenarios":"Calling request_data with a custom data type (e.g. BinanceFuturesOpenInterestHist) whose DataType metadata either has no `instrument_id` key, has a non-string value, or a blank/whitespace string.","commonSituations":"Building a DataCmd programmatically and forgetting the metadata entry, copying example code without the metadata map, or passing an ID wrapped in quotes/whitespace.","solutions":["Add `instrument_id` to the custom data request metadata as a non-empty string","Ensure the value is a valid InstrumentId parseable by the adapter (e.g. BTCUSDT-PERP.BINANCE)","Trim whitespace from the configured value","Fix surrounding code if the metadata is a serde map being silently dropped (wrong serialization type)"],"exampleFix":"// before\nlet data_type = DataType::new(\"BinanceFuturesOpenInterestHist\", None);\n// after\nlet metadata = indexmap::IndexMap::from([(\"instrument_id\".to_string(), serde_json::json!(\"BTCUSDT-PERP.BINANCE\"))]);\nlet data_type = DataType::new(\"BinanceFuturesOpenInterestHist\", Some(metadata));","handlingStrategy":"validation","validationCode":"let id = data_type.metadata()\n    .and_then(|m| m.get(\"instrument_id\"))\n    .and_then(|v| v.as_str())\n    .map(str::trim)\n    .filter(|s| !s.is_empty());\nassert!(id.is_some(), \"instrument_id metadata required\");","typeGuard":"fn has_instrument_id(meta: &Option<IndexMap<String, serde_json::Value>>) -> bool {\n    meta.as_ref().and_then(|m| m.get(\"instrument_id\")).and_then(|v| v.as_str()).map(str::trim).map_or(false, |s| !s.is_empty())\n}","tryCatchPattern":"match client.request_data(data_type).await {\n    Err(e) if e.to_string().contains(\"requires `instrument_id` metadata\") => return Err(anyhow::anyhow!(\"add instrument_id metadata to request\")),\n    other => other,\n}","preventionTips":["Always include instrument_id in custom data metadata","Use a shared builder function for custom DataCmds","Trim configured instrument ids"],"tags":["rust","metadata","validation","binance"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}