nautechsystems/nautilus_trader · error

Invalid config type for BinanceDataClientFactory. Expected B

Error message

Invalid config type for BinanceDataClientFactory. Expected BinanceDataClientConfig, was {config:?}

What it means

BinanceDataClientFactory.create downcasts the generic ClientConfig it receives to BinanceDataClientConfig; when a different config type is passed (e.g. BinanceExecClientConfig, a stub, or a dynamically-built config from another adapter), the downcast returns None and this error names the actual type via its Debug output.

Source

Thrown at crates/adapters/binance/src/factories.rs:80

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

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

        let client_id = ClientId::from(name);

        binance_config.validate()?;

        let product_type = binance_config.product_type;

        match product_type {
            BinanceProductType::Spot => {
                let client = BinanceSpotDataClient::new(client_id, binance_config)?;
                Ok(Box::new(client))
            }
            BinanceProductType::UsdM | BinanceProductType::CoinM => {
                let client =

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Pass a BinanceDataClientConfig instance to BinanceDataClientFactory.create (the config_type() name check helps log mismatches).
  2. Check the error's {config:?} Debug output to see which concrete type was actually supplied.
  3. If driving factories generically, dispatch on config_type() == stringify!(BinanceDataClientConfig) before calling create.

Example fix

// before
let client = BinanceDataClientFactory.create(name, &exec_config, cache, clock)?; // exec config!

// after
let client = BinanceDataClientFactory.create(name, &data_config, cache, clock)?; // BinanceDataClientConfig
Defensive patterns

Strategy: type-guard

Type guard

fn is_binance_data_config(config: &dyn ClientConfig) -> bool {
    config.as_any().downcast_ref::<BinanceDataClientConfig>().is_some()
}

Try / catch

match BinanceDataClientFactory.create(name, config, cache, clock) {
    Err(e) if e.to_string().contains('Invalid config type') => {
        return Err(anyhow::anyhow!(
            'wiring error: {config:?} routed to the Binance data factory'
        ));
    }
    result => result,
}

Prevention

When it happens

Trigger: Registering BinanceDataClientFactory with a config object that is not BinanceDataClientConfig — for example swapping the data/exec config arguments in a factory wiring layer, or a custom ClientConfig implementation passed through a generic framework path.

Common situations: Building custom infrastructure on top of the factory traits (Rust users); passing an exec config where a data config belongs; a serde round-trip that reconstructed the config as the wrong concrete type.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/a80ad553613e3e7e. Report an issue: GitHub.