nautechsystems/nautilus_trader · error
Invalid config type for OKXDataClientFactory. Expected OKXDa
Error message
Invalid config type for OKXDataClientFactory. Expected OKXDataClientConfig, was {config:?} What it means
OKXDataClientFactory::create only accepts a config object that downcasts to OKXDataClientConfig. When the registered config type differs (wrong adapter config passed to the factory), the downcast fails and the factory refuses to construct a data client, echoing the actual config's debug representation.
Source
Thrown at crates/adapters/okx/src/factories.rs:92
impl Default for OKXDataClientFactory {
fn default() -> Self {
Self::new()
}
}
impl DataClientFactory for OKXDataClientFactory {
fn create(
&self,
name: &str,
config: &dyn ClientConfig,
_cache: CacheView,
_clock: Rc<RefCell<dyn Clock>>,
) -> anyhow::Result<Box<dyn DataClient>> {
let okx_config = config
.as_any()
.downcast_ref::<OKXDataClientConfig>()
.ok_or_else(|| {
anyhow::anyhow!(
"Invalid config type for OKXDataClientFactory. Expected OKXDataClientConfig, was {config:?}",
)
})?
.clone();
let client_id = ClientId::from(name);
let client = OKXDataClient::new(client_id, okx_config)?;
Ok(Box::new(client))
}
fn name(&self) -> &'static str {
OKX
}
fn config_type(&self) -> &'static str {
"OKXDataClientConfig"
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the config passed for client name is constructed as OKXDataClientConfig (or deserialized into it).
- Check the trader's client registration map so each factory name maps to the matching OKX config type.
- Fix the config file/serialization so the concrete type tag identifies OKXDataClientConfig.
Example fix
// before let config = DataClientConfig::new(...) ; factory.create(name, config.boxed(), ...) // after let config = OKXDataClientConfig::new(api_key, api_secret, passphrase); factory.create(name, Box::new(config), ...);
Defensive patterns
Strategy: type-guard
Validate before calling
fn is_okx_data_config(cfg: &dyn ClientConfig) -> bool {
cfg.as_any().downcast_ref::<OKXDataClientConfig>().is_some()
} Type guard
fn as_okx_data_config(cfg: &dyn ClientConfig) -> Option<&OKXDataClientConfig> {
cfg.as_any().downcast_ref::<OKXDataClientConfig>()
} Try / catch
match as_okx_data_config(config.as_ref()) {
Some(okx_cfg) => factory.create(name, config, clock, cache),
None => return Err(anyhow!("expected OKXDataClientConfig, got {config:?}")),
} Prevention
- Register each venue factory only with its matching config type.
- When deserializing configs, use tagged enums keyed by venue so concrete types are preserved.
- Add a unit test asserting factory/config pairing for every venue in your setup.
When it happens
Trigger: Calling OKXDataClientFactory::create with a ClientConfig that is not OKXDataClientConfig, e.g. a BinanceDataClientConfig, generic DataClientConfig, or deserialized config whose concrete type was lost.
Common situations: Mixing adapter configs when running multiple venues; loading client configs from JSON/TOML where the type tag is wrong; renaming or refactoring config structs across versions.
Related errors
- Invalid config type for OKXExecutionClientFactory. Expected
- Invalid config type for BlockchainDataClientFactory. Expecte
- Invalid config type for BlockchainExecutionClientFactory. Ex
- Invalid config type for BybitDataClientFactory. Expected Byb
- Invalid config type for BybitExecutionClientFactory. Expecte
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dd5b83d792b8aa66.
Report an issue: GitHub.