nautechsystems/nautilus_trader · error · anyhow::Error

Invalid config type for BitmexDataClientFactory. Expected…

Error message

Invalid config type for BitmexDataClientFactory. Expected BitmexDataClientConfig, was {config:?}

What it means

BitmexDataClientFactory::create only accepts a config object that downcasts to BitmexDataClientConfig. Any other config type passed to the factory produces this error naming both the expected type and the actual config value.

Solutions

  1. Pass a BitmexDataClientConfig instance to BitmexDataClientFactory::create.
  2. Check the config section of your node/trading config maps to the data client, not the execution client.
  3. Rebuild the config via the factory's expected type or a deserialization into BitmexDataClientConfig.
  4. Compare the debug output in the message (was {config:?}) against the expected struct to spot the mismatch.

Example fix

// before
let config = BitmexExecutionClientConfig { ... };
let client = BitmexDataClientFactory.create(name, config, ...);
// after
let config = BitmexDataClientConfig { api_key, api_secret, ... };
let client = BitmexDataClientFactory.create(name, config, ...);
Defensive patterns

Strategy: type-guard

Validate before calling

// Rust
fn is_bitmex_data_config(config: &dyn Any) -> bool {
    config.downcast_ref::<BitmexDataClientConfig>().is_some()
}

Type guard

// Rust
fn as_bitmex_data_config(config: &dyn Any) -> Option<&BitmexDataClientConfig> {
    config.downcast_ref::<BitmexDataClientConfig>()
}

Try / catch

// Rust
let cfg = config.as_any()
    .downcast_ref::<BitmexDataClientConfig>()
    .ok_or_else(|| anyhow::anyhow!("expected BitmexDataClientConfig, got {:?}", config))?;

Prevention

When it happens

Trigger: Calling create on BitmexDataClientFactory with a config whose as_any().downcast_ref::<BitmexDataClientConfig>() returns None — e.g. passing BitmexExecutionClientConfig, a generic client config, or a config built for another venue.

Common situations: Registering the data client factory with the wrong config in a node config file, copy-pasting execution client config into the data client slot, or using a renamed/moved config struct after a version upgrade.

Related errors


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

Appendix: source

Thrown at crates/adapters/bitmex/src/factories.rs:89

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

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

        let client_id = ClientId::from(name);
        let client = BitmexDataClient::new(client_id, bitmex_config)?;
        Ok(Box::new(client))
    }

    fn name(&self) -> &'static str {
        BITMEX
    }

    fn config_type(&self) -> &'static str {
        "BitmexDataClientConfig"
    }
}

View on GitHub (pinned to 18893faf8b)