{"record":{"id":"dbbf7a67dab73246","repo":"nautechsystems/nautilus_trader","slug":"spot-ticker-requires-a-binance-instrument","errorCode":null,"errorMessage":"Spot ticker requires a BINANCE instrument","messagePattern":"Spot ticker requires a BINANCE instrument","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/spot/data.rs","lineNumber":1773,"sourceCode":"\n    fn is_disconnected(&self) -> bool {\n        !self.is_connected()\n    }\n\n    fn subscribe(&mut self, cmd: SubscribeCustomData) -> anyhow::Result<()> {\n        if cmd.data_type.type_name() != \"BinanceSpotTicker\" {\n            log::warn!(\n                \"Unsupported custom data subscription: {}\",\n                cmd.data_type.type_name()\n            );\n            return Ok(());\n        }\n        anyhow::ensure!(\n            self.spot_market_data_mode == BinanceSpotMarketDataMode::Json,\n            \"Binance Spot 24-hour ticker custom data requires JSON market-data mode\"\n        );\n        let instrument_id = Self::required_instrument_id_metadata(&cmd.data_type)?;\n        anyhow::ensure!(\n            instrument_id.venue == self.venue(),\n            \"Spot ticker requires a BINANCE instrument\"\n        );\n        let should_subscribe = {\n            let previous = self\n                .ticker_refs\n                .load()\n                .get(&instrument_id)\n                .copied()\n                .unwrap_or(0);\n            self.ticker_refs\n                .rcu(|refs| *refs.entry(instrument_id).or_insert(0) += 1);\n            previous == 0\n        };\n\n        if should_subscribe {\n            let ws = self.ws_client.clone();\n            let stream = format!(\"{}@ticker\", instrument_id.symbol.as_str().to_lowercase());","sourceCodeStart":1755,"sourceCodeEnd":1791,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/spot/data.rs#L1755-L1791","documentation":"For a BinanceSpotTicker custom data subscription, the DataType metadata must include an instrument_id whose venue equals the data client's venue (BINANCE for Spot). Any other venue in the metadata (a typo, another exchange, or a synthetic venue) is rejected by this check.","triggerScenarios":"Subscribing to BinanceSpotTicker custom data whose instrument_id metadata reads e.g. 'BTCUSDT.BYBIT' or 'BTCUSDT.BINANCE_SPOT' instead of a BINANCE-venue instrument ID.","commonSituations":"Copy-pasting subscription setup from another adapter; constructing the DataType metadata manually with a wrong venue string; multi-venue routing code applying the wrong venue suffix.","solutions":["Set the DataType metadata instrument_id to a BINANCE-venue instrument, e.g. 'BTCUSDT.BINANCE'","If routing between venues, verify the venue suffix is derived from the target adapter before constructing the custom data type"],"exampleFix":"# before\ndata_type = DataType(\n    name=\"BinanceSpotTicker\",\n    metadata={\"instrument_id\": \"BTCUSDT.BYBIT\"},  # wrong venue\n)\n\n# after\nfrom nautilus_trader.model.identifiers import InstrumentId\ndata_type = DataType(\n    name=\"BinanceSpotTicker\",\n    metadata={\"instrument_id\": str(InstrumentId.from_str(\"BTCUSDT.BINANCE\"))},\n)","handlingStrategy":"type-guard","validationCode":"from nautilus_trader.model.identifiers import InstrumentId\n\ndef is_binance_instrument(instrument_id: str) -> bool:\n    return InstrumentId.from_str(instrument_id).venue == \"BINANCE\"","typeGuard":"def is_binance_instrument(instrument_id: str) -> bool:\n    from nautilus_trader.model.identifiers import InstrumentId\n    try:\n        return InstrumentId.from_str(instrument_id).venue == \"BINANCE\"\n    except ValueError:\n        return False","tryCatchPattern":null,"preventionTips":["Derive instrument IDs from the adapter's instrument provider instead of hand-building strings","In multi-venue setups, assert the venue suffix matches the target adapter before subscribing"],"tags":["binance","spot","instrument-id","venue","custom-data","validation"],"backgroundTag":"instrument-venue-mismatch","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}