{"record":{"id":"4cc19cd79e25978e","repo":"nautechsystems/nautilus_trader","slug":"invalid-config-type-for-dydxdataclientfactory-exp","errorCode":null,"errorMessage":"Invalid config type for DydxDataClientFactory. Expected DydxDataClientConfig, was {config:?}","messagePattern":"Invalid config type for DydxDataClientFactory\\. Expected DydxDataClientConfig, was (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/factories.rs","lineNumber":98,"sourceCode":"impl Default for DydxDataClientFactory {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl DataClientFactory for DydxDataClientFactory {\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 dydx_config = config\n            .as_any()\n            .downcast_ref::<DydxDataClientConfig>()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Invalid config type for DydxDataClientFactory. Expected DydxDataClientConfig, was {config:?}\",\n                )\n            })?\n            .clone();\n\n        let client_id = ClientId::from(name);\n\n        let http_url = dydx_config\n            .base_url_http\n            .clone()\n            .unwrap_or_else(|| urls::http_base_url(dydx_config.network).to_string());\n        let ws_url = dydx_config\n            .base_url_ws\n            .clone()\n            .unwrap_or_else(|| urls::ws_url(dydx_config.network).to_string());\n\n        let retry_config = Some(RetryConfig {\n            max_retries: dydx_config.max_retries as u32,","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/factories.rs#L80-L116","documentation":"DydxDataClientFactory::create receives a generic config object and downcasts it to DydxDataClientConfig. If the passed config is a different type (e.g. the execution client's config, or another adapter's config), the downcast fails and this error is returned instead of building a data client.","triggerScenarios":"Calling DydxDataClientFactory.create(name, config, ...) with a config whose as_any().downcast_ref::<DydxDataClientConfig>() returns None — most commonly passing DydxExecutionClientConfig, or a config from a different adapter.","commonSituations":"Swapping factory/config pairs in the trading node configuration (execution config given to the data factory); YAML/JSON config where the config type key was mistyped or copy-pasted between data and execution client blocks; tests that deliberately pass a wrong config to verify rejection.","solutions":["Pass a DydxDataClientConfig instance to DydxDataClientFactory.create.","Check your node config so the data-client section uses the data client config type and the execution-client section uses DydxExecutionClientConfig.","In Python, construct the config via DydxDataClientConfig(...) from the dydx adapter package rather than reusing another adapter's config class.","If migrating adapters, update both the factory and the config class names together."],"exampleFix":"# before\n# data_config = DydxExecutionClientConfig(...)  # wrong type\n# factory.create(name, data_config, ...)\n# after\ndata_config = DydxDataClientConfig(instrument_provider=InstrumentProviderConfig(load_all=True))\nclient = DydxDataClientFactory().create(name, data_config, ...)","handlingStrategy":"type-guard","validationCode":"assert isinstance(config, DydxDataClientConfig), f\"expected DydxDataClientConfig, got {type(config)}\"","typeGuard":"fn as_dydx_data_config(config: &dyn DataClientConfig) -> Option<&DydxDataClientConfig> {\n    config.as_any().downcast_ref::<DydxDataClientConfig>()\n}","tryCatchPattern":"match DydxDataClientFactory().create(name, config, ...) {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"Invalid config type\") => {\n        // inspect config type and use the matching factory\n        panic!(\"wrong config for data factory: {e}\")\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Pair each factory with its own config class (data vs execution)","Double-check YAML/JSON node config blocks are not swapped","Construct configs from the dydx adapter's exported classes"],"tags":["dydx","factory","config","downcast","type-mismatch"],"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"}