{"record":{"id":"8bb346fffef2d168","repo":"nautechsystems/nautilus_trader","slug":"binance-futures-custom-data-requires-binance-venue","errorCode":null,"errorMessage":"Binance Futures custom data requires BINANCE venue instrument, received {instrument_id}","messagePattern":"Binance Futures custom data requires BINANCE venue instrument, received (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/data.rs","lineNumber":2691,"sourceCode":"                        }\n                    }\n                    Err(e) => log::error!(\"BinanceBar request failed for {bar_type}: {e:?}\"),\n                }\n            });\n            return Ok(());\n        }\n\n        if data_type_name != \"BinanceFuturesOpenInterest\"\n            && data_type_name != \"BinanceFuturesOpenInterestHist\"\n        {\n            log::warn!(\"Unsupported custom data request: {data_type_name}\");\n            return Ok(());\n        }\n\n        let instrument_id = Self::required_instrument_id_metadata(&data_type)?;\n\n        if instrument_id.venue != self.venue() {\n            anyhow::bail!(\n                \"Binance Futures custom data requires BINANCE venue instrument, received {instrument_id}\"\n            );\n        }\n\n        let period = if data_type_name == \"BinanceFuturesOpenInterestHist\" {\n            Some(Self::required_period_metadata(&data_type)?)\n        } else {\n            None\n        };\n\n        let http = self.http_client.clone();\n        let sender = self.data_sender.clone();\n        let request_id = request.request_id;\n        let client_id = request.client_id;\n        let params = request.params;\n        let clock = self.clock;\n        let venue = self.venue();\n        let limit = request.limit.map(|n| n.get() as u32);","sourceCodeStart":2673,"sourceCodeEnd":2709,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/futures/data.rs#L2673-L2709","documentation":"`BinanceFuturesOpenInterest` and `BinanceFuturesOpenInterestHist` custom-data requests first parse the `instrument_id` metadata, then require its venue to equal the data client's venue (BINANCE). A wrong-venue instrument id is rejected before the period check (for Hist) and before the spawned HTTP fetch, so no request reaches Binance.","triggerScenarios":"`request_data` with data type name `BinanceFuturesOpenInterest` or `BinanceFuturesOpenInterestHist` and metadata `{'instrument_id': 'BTC-PERP.BYBIT', ...}` — any parsed InstrumentId whose venue is not BINANCE. Missing/empty instrument_id metadata fails earlier with the separate 'custom data request requires `instrument_id` metadata' error.","commonSituations":"Sharing one metadata dict across venue clients; typo'd venue suffix in config; multi-venue research code requesting open interest for every instrument in a watchlist without filtering by venue.","solutions":["Use a BINANCE futures instrument id, e.g. {'instrument_id': 'BTCUSDT-PERP.BINANCE', 'period': '1h'} for the Hist variant","Filter your instrument universe by venue before issuing open-interest requests to this client"],"exampleFix":"# before\nmeta = {'instrument_id': 'BTCUSDT-PERP.BYBIT', 'period': '1h'}\nactor.request_custom_data(DataType(BinanceFuturesOpenInterestHist, meta), ...)\n\n# after\nmeta = {'instrument_id': 'BTCUSDT-PERP.BINANCE', 'period': '1h'}\nactor.request_custom_data(DataType(BinanceFuturesOpenInterestHist, meta), ...)","handlingStrategy":"validation","validationCode":"def build_oi_request_metadata(data_type_name: str, instrument_id) -> dict:\n    if instrument_id.venue.value != 'BINANCE':\n        raise ValueError(f'{data_type_name} requests need a BINANCE instrument, got {instrument_id}')\n    meta = {'instrument_id': str(instrument_id)}\n    if data_type_name == 'BinanceFuturesOpenInterestHist':\n        meta['period'] = '1h'  # required; one of 5m..1d\n    return meta","typeGuard":"def is_binance_instrument(instrument_id) -> bool:\n    return instrument_id.venue.value == 'BINANCE'","tryCatchPattern":"try:\n    actor.request_custom_data(data_type, ...)\nexcept Exception as e:\n    if 'custom data requires BINANCE venue instrument' in str(e):\n        raise ValueError('Filter your instrument universe by venue before sending open-interest requests to the Binance client') from e\n    raise","preventionTips":["Filter multi-venue instrument lists by venue before requesting open interest","Generate the metadata instrument_id from the traded InstrumentId object, not from free-text config"],"tags":["binance","futures","open-interest","venue","request-validation"],"backgroundTag":"venue-mismatch","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}