{"record":{"id":"b73e1d452aab0a1d","repo":"nautechsystems/nautilus_trader","slug":"invalid-config-type-for-interactivebrokersdataclie","errorCode":null,"errorMessage":"Invalid config type for InteractiveBrokersDataClientFactory. Expected InteractiveBrokersDataClientConfig, was {config:?}","messagePattern":"Invalid config type for InteractiveBrokersDataClientFactory\\. Expected InteractiveBrokersDataClientConfig, was (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/factories.rs","lineNumber":95,"sourceCode":"impl Default for InteractiveBrokersDataClientFactory {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl DataClientFactory for InteractiveBrokersDataClientFactory {\n    fn create(\n        &self,\n        name: &str,\n        config: &dyn ClientConfig,\n        cache: CacheView,\n        _clock: Rc<RefCell<dyn Clock>>,\n    ) -> anyhow::Result<Box<dyn DataClient>> {\n        let ib_config = config\n            .as_any()\n            .downcast_ref::<InteractiveBrokersDataClientConfig>()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Invalid config type for InteractiveBrokersDataClientFactory. Expected InteractiveBrokersDataClientConfig, was {config:?}\",\n                )\n            })?\n            .clone();\n\n        let instrument_provider = Arc::new(InteractiveBrokersInstrumentProvider::new(\n            ib_config.instrument_provider.clone(),\n        ));\n        seed_provider_from_cache(&instrument_provider, &cache);\n        let client = InteractiveBrokersDataClient::new(\n            ClientId::from(name),\n            ib_config,\n            instrument_provider,\n        )?;\n        Ok(Box::new(client))\n    }\n\n    fn name(&self) -> &'static str {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/factories.rs#L77-L113","documentation":"InteractiveBrokersDataClientFactory::create requires the generic client config passed down from the node to be exactly InteractiveBrokersDataClientConfig. It performs a downcast of the `dyn ClientConfig` and, if the concrete type differs, returns this error instead of building a client. This guards against wiring a wrong or incompatible config object to the IB data client factory.","triggerScenarios":"Building a data client via InteractiveBrokersDataClientFactory with any config other than InteractiveBrokersDataClientConfig (e.g. an execution client config, another adapter's config, or a custom config struct).","commonSituations":"Copy-pasting client factory wiring and passing the execution client's config to the data client factory; composing a node from a template where config types got swapped; a custom config type that merely resembles the IB config.","solutions":["Pass an InteractiveBrokersDataClientConfig instance when creating the data client through this factory.","Check the `config:?` debug dump in the message to identify the concrete type actually passed.","If using a wrapper/subclass config, flatten it into a plain InteractiveBrokersDataClientConfig.","Verify the factory registered in the client builder matches the config type (data factory for data config)."],"exampleFix":"// before\nlet config = InteractiveBrokersExecClientConfig::default();\ndata_engine.register_client(factory.create(\"IB\", config)?)?;\n// after\nlet config = InteractiveBrokersDataClientConfig::default();\ndata_engine.register_client(factory.create(\"IB\", config)?)?;","handlingStrategy":"type-guard","validationCode":"// ensure concrete type before handing to factory\nlet cfg: &InteractiveBrokersDataClientConfig = config\n    .as_any()\n    .downcast_ref::<InteractiveBrokersDataClientConfig>()\n    .expect(\"data factory requires InteractiveBrokersDataClientConfig\");","typeGuard":"fn is_ib_data_config(config: &dyn ClientConfig) -> bool {\n    config.as_any().downcast_ref::<InteractiveBrokersDataClientConfig>().is_some()\n}","tryCatchPattern":"match factory.create(name, config, clock) {\n    Ok(client) => register(client),\n    Err(e) if e.to_string().contains(\"Invalid config type for InteractiveBrokersDataClientFactory\") => {\n        panic!(\"wiring bug: wrong config passed to IB data factory: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Pair each factory with its matching config type at registration sites","Add a compile-time annotation or alias clarifying which config goes to which factory","Cover node wiring in an integration test that builds all clients"],"tags":["config","factory","downcast"],"backgroundTag":"config-type-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}