nautechsystems/nautilus_trader · error · anyhow::Error

Invalid config type for DydxDataClientFactory. Expected Dydx

Error message

Invalid config type for DydxDataClientFactory. Expected DydxDataClientConfig, was {config:?}

What it means

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.

Source

Thrown at crates/adapters/dydx/src/factories.rs:98

impl Default for DydxDataClientFactory {
    fn default() -> Self {
        Self::new()
    }
}

impl DataClientFactory for DydxDataClientFactory {
    fn create(
        &self,
        name: &str,
        config: &dyn ClientConfig,
        _cache: CacheView,
        _clock: Rc<RefCell<dyn Clock>>,
    ) -> anyhow::Result<Box<dyn DataClient>> {
        let dydx_config = config
            .as_any()
            .downcast_ref::<DydxDataClientConfig>()
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "Invalid config type for DydxDataClientFactory. Expected DydxDataClientConfig, was {config:?}",
                )
            })?
            .clone();

        let client_id = ClientId::from(name);

        let http_url = dydx_config
            .base_url_http
            .clone()
            .unwrap_or_else(|| urls::http_base_url(dydx_config.network).to_string());
        let ws_url = dydx_config
            .base_url_ws
            .clone()
            .unwrap_or_else(|| urls::ws_url(dydx_config.network).to_string());

        let retry_config = Some(RetryConfig {
            max_retries: dydx_config.max_retries as u32,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a DydxDataClientConfig instance to DydxDataClientFactory.create.
  2. Check your node config so the data-client section uses the data client config type and the execution-client section uses DydxExecutionClientConfig.
  3. In Python, construct the config via DydxDataClientConfig(...) from the dydx adapter package rather than reusing another adapter's config class.
  4. If migrating adapters, update both the factory and the config class names together.

Example fix

# before
# data_config = DydxExecutionClientConfig(...)  # wrong type
# factory.create(name, data_config, ...)
# after
data_config = DydxDataClientConfig(instrument_provider=InstrumentProviderConfig(load_all=True))
client = DydxDataClientFactory().create(name, data_config, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(config, DydxDataClientConfig), f"expected DydxDataClientConfig, got {type(config)}"

Type guard

fn as_dydx_data_config(config: &dyn DataClientConfig) -> Option<&DydxDataClientConfig> {
    config.as_any().downcast_ref::<DydxDataClientConfig>()
}

Try / catch

match DydxDataClientFactory().create(name, config, ...) {
    Ok(c) => c,
    Err(e) if e.to_string().contains("Invalid config type") => {
        // inspect config type and use the matching factory
        panic!("wrong config for data factory: {e}")
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4cc19cd79e25978e. Report an issue: GitHub.