{"record":{"id":"b67ff002004b00e1","repo":"nautechsystems/nautilus_trader","slug":"invalid-config-type-for-hyperliquiddataclientfacto","errorCode":null,"errorMessage":"Invalid config type for HyperliquidDataClientFactory. Expected HyperliquidDataClientConfig, was {config:?}","messagePattern":"Invalid config type for HyperliquidDataClientFactory\\. Expected HyperliquidDataClientConfig, was (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/factories.rs","lineNumber":89,"sourceCode":"impl Default for HyperliquidDataClientFactory {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl DataClientFactory for HyperliquidDataClientFactory {\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 hyperliquid_config = config\n            .as_any()\n            .downcast_ref::<HyperliquidDataClientConfig>()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Invalid config type for HyperliquidDataClientFactory. Expected HyperliquidDataClientConfig, was {config:?}\",\n                )\n            })?\n            .clone();\n\n        let client_id = ClientId::from(name);\n        let client = HyperliquidDataClient::new(client_id, hyperliquid_config)?;\n        Ok(Box::new(client))\n    }\n\n    fn name(&self) -> &'static str {\n        HYPERLIQUID\n    }\n\n    fn config_type(&self) -> &'static str {\n        \"HyperliquidDataClientConfig\"\n    }\n}","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/factories.rs#L71-L107","documentation":"HyperliquidDataClientFactory::create() downcasts the generic config to HyperliquidDataClientConfig and fails when the provided config is any other type. Factories are type-erased, so a config wired to the wrong factory produces this error.","triggerScenarios":"Passing a HyperliquidExecutionClientConfig (or any other client config) to the data client factory — typically via a misconfigured client registration in the node config, e.g. mapping the wrong config type to the HYPERLIQUID data client name.","commonSituations":"Copy-paste mistakes in TradingNode config where execution and data client configs are swapped; JSON/TOML config deserializing into the wrong config struct; programmatic wiring putting the wrong config object into the factory map.","solutions":["Ensure the config registered for the Hyperliquid data client is a HyperliquidDataClientConfig","Check the node builder wiring: .data_clients(...) must pair HyperliquidDataClientConfig with the data factory","Fix JSON/TOML config so the data client section deserializes into HyperliquidDataClientConfig","Log {config:?} (already in the message) to see which type was actually passed"],"exampleFix":"// before\nnode_builder.add_data_client_factory(\"HYPERLIQUID\", HyperliquidDataClientFactory(), exec_config);\n// after\nnode_builder.add_data_client_factory(\"HYPERLIQUID\", HyperliquidDataClientFactory(), data_config);","handlingStrategy":"type-guard","validationCode":"if config.as_any().downcast_ref::<HyperliquidDataClientConfig>().is_none() {\n    panic!(\"data client config must be HyperliquidDataClientConfig\");\n}","typeGuard":"fn is_data_config(config: &dyn ClientConfig) -> bool {\n    config.as_any().downcast_ref::<HyperliquidDataClientConfig>().is_some()\n}","tryCatchPattern":"match factory.create(name, config, cache, clock) { Err(e) if e.to_string().contains(\"Invalid config type\") => fix_client_wiring(), other => other }","preventionTips":["Pair each factory with its matching config type in the node builder","Keep data and execution configs in separate, clearly named config variables","Validate the JSON/TOML client sections against the right config structs at startup","Check the {config:?} debug output in the error to see what was actually passed"],"tags":["config","factory","hyperliquid","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"}