nautechsystems/nautilus_trader · error · anyhow::Error
Invalid config type for HyperliquidDataClientFactory. Expect
Error message
Invalid config type for HyperliquidDataClientFactory. Expected HyperliquidDataClientConfig, was {config:?} What it means
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.
Source
Thrown at crates/adapters/hyperliquid/src/factories.rs:89
impl Default for HyperliquidDataClientFactory {
fn default() -> Self {
Self::new()
}
}
impl DataClientFactory for HyperliquidDataClientFactory {
fn create(
&self,
name: &str,
config: &dyn ClientConfig,
_cache: CacheView,
_clock: Rc<RefCell<dyn Clock>>,
) -> anyhow::Result<Box<dyn DataClient>> {
let hyperliquid_config = config
.as_any()
.downcast_ref::<HyperliquidDataClientConfig>()
.ok_or_else(|| {
anyhow::anyhow!(
"Invalid config type for HyperliquidDataClientFactory. Expected HyperliquidDataClientConfig, was {config:?}",
)
})?
.clone();
let client_id = ClientId::from(name);
let client = HyperliquidDataClient::new(client_id, hyperliquid_config)?;
Ok(Box::new(client))
}
fn name(&self) -> &'static str {
HYPERLIQUID
}
fn config_type(&self) -> &'static str {
"HyperliquidDataClientConfig"
}
}View on GitHub (pinned to 18893faf8b)
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
Example fix
// before
node_builder.add_data_client_factory("HYPERLIQUID", HyperliquidDataClientFactory(), exec_config);
// after
node_builder.add_data_client_factory("HYPERLIQUID", HyperliquidDataClientFactory(), data_config); Defensive patterns
Strategy: type-guard
Validate before calling
if config.as_any().downcast_ref::<HyperliquidDataClientConfig>().is_none() {
panic!("data client config must be HyperliquidDataClientConfig");
} Type guard
fn is_data_config(config: &dyn ClientConfig) -> bool {
config.as_any().downcast_ref::<HyperliquidDataClientConfig>().is_some()
} Try / catch
match factory.create(name, config, cache, clock) { Err(e) if e.to_string().contains("Invalid config type") => fix_client_wiring(), other => other } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid config type for HyperliquidExecutionClientFactory. E
- Invalid config type for BetfairDataClientFactory. Expected B
- Invalid config type for BetfairExecutionClientFactory. Expec
- Invalid config type for BitmexDataClientFactory. Expected Bi
- Invalid config type for BitmexExecutionClientFactory. Expect
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b67ff002004b00e1.
Report an issue: GitHub.