{"record":{"id":"73b9375643799193","repo":"nautechsystems/nautilus_trader","slug":"binance-v2-does-not-support-instrument-filter-call","errorCode":null,"errorMessage":"Binance v2 does not support instrument filter_callable {filter_callable:?}; the legacy Binance provider never applied callable filters","messagePattern":"Binance v2 does not support instrument filter_callable (.+?); the legacy Binance provider never applied callable filters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/config.rs","lineNumber":88,"sourceCode":"        Self::builder().build()\n    }\n}\n\nimpl BinanceInstrumentProviderConfig {\n    /// Validates instrument loading configuration.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error for malformed IDs, unsupported filters, or a legacy\n    /// callable filter that Binance v2 cannot execute safely.\n    pub fn validate(&self, product_type: BinanceProductType) -> anyhow::Result<()> {\n        if let Some(filter_callable) = self\n            .filter_callable\n            .as_deref()\n            .map(str::trim)\n            .filter(|value| !value.is_empty())\n        {\n            anyhow::bail!(\n                \"Binance v2 does not support instrument filter_callable {filter_callable:?}; \\\n                 the legacy Binance provider never applied callable filters\"\n            );\n        }\n\n        if let Some(load_ids) = &self.load_ids {\n            for raw in load_ids {\n                let instrument_id = InstrumentId::from_str(raw)\n                    .map_err(|e| anyhow::anyhow!(\"invalid Binance load_ids value {raw:?}: {e}\"))?;\n                anyhow::ensure!(\n                    instrument_id.venue.as_str() == \"BINANCE\",\n                    \"Binance load_ids value {raw:?} must use venue BINANCE\"\n                );\n            }\n        }\n\n        for (key, value) in &self.filters {\n            let supported = matches!(key.as_str(), \"symbols\" | \"bases\" | \"quotes\")","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/config.rs#L70-L106","documentation":"BinanceDataClientConfig.validate rejects the instrument_provider's filter_callable option. The v2 Binance adapter is written in Rust and cannot safely execute arbitrary Python callables while loading instruments, and the legacy provider never actually applied such filters anyway, so the config fails validation rather than silently ignoring the filter.","triggerScenarios":"Setting BinanceFuturesInstrumentProviderConfig(filter_callable=my_fn) (or the equivalent dict/kwargs) on the Binance v2 instrument provider config, then calling config.validate() (which the factory runs automatically on client creation).","commonSituations":"Migrating a config from the legacy Python Binance adapter or BinanceDataClientConfig snippets found in older docs/blog posts; copy-pasting a provider config that filters instruments with a lambda; attempting to narrow a huge universe (thousands of symbols) with a custom predicate.","solutions":["Remove filter_callable from the instrument provider config entirely.","Express the filter declaratively with the supported keys: filters={'symbols': [...]} , {'bases': [...]} or {'quotes': [...]}, or use load_ids=['BTCUSDT.BINANCE', ...].","If you need predicate-style filtering, load a superset via filters and drop unwanted instruments in your strategy after they arrive in the cache."],"exampleFix":"# before\nconfig = BinanceDataClientConfig(\n    instrument_provider=BinanceFuturesInstrumentProviderConfig(\n        filter_callable=lambda i: i.base == 'USDT',\n    ),\n)\n\n# after\nconfig = BinanceDataClientConfig(\n    instrument_provider=BinanceFuturesInstrumentProviderConfig(\n        filters={'quotes': ['USDT']},\n    ),\n)","handlingStrategy":"validation","validationCode":"cfg = BinanceDataClientConfig(\n    instrument_provider=BinanceFuturesInstrumentProviderConfig(\n        load_ids=['BTCUSDT.BINANCE'],\n        filters={'quotes': ['USDT']},\n    ),\n)\ncfg.validate()  # fails fast if filter_callable or a bad filter slipped in","typeGuard":null,"tryCatchPattern":"try:\n    cfg.validate()\nexcept Exception as e:\n    raise SystemExit(f'Binance config rejected at startup: {e}')","preventionTips":["Do not carry filter_callable over from legacy v1 adapter configs.","Express instrument narrowing with filters (symbols/bases/quotes/contract_types) or load_ids.","Call config.validate() immediately after building any Binance client config."],"tags":["binance","config","instrument-provider","migration","validation"],"backgroundTag":"unsupported-config-option","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}