nautechsystems/nautilus_trader · error

Invalid config type for BinanceExecutionClientFactory. Expec

Error message

Invalid config type for BinanceExecutionClientFactory. Expected BinanceExecClientConfig, was {config:?}

What it means

BinanceExecutionClientFactory.create downcasts the incoming ClientConfig to BinanceExecClientConfig. Passing any other concrete type (e.g. BinanceDataClientConfig) makes the downcast fail and the error reports the actual type's Debug representation so the wiring mistake is visible.

Source

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

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

impl ExecutionClientFactory for BinanceExecutionClientFactory {
    fn create(
        &self,
        name: &str,
        config: &dyn ClientConfig,
        cache: CacheView,
    ) -> anyhow::Result<Box<dyn ExecutionClient>> {
        let binance_config = config
            .as_any()
            .downcast_ref::<BinanceExecClientConfig>()
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "Invalid config type for BinanceExecutionClientFactory. Expected BinanceExecClientConfig, was {config:?}",
                )
            })?
            .clone();

        let product_type = binance_config.product_type;

        binance_config.validate()?;

        match product_type {
            BinanceProductType::Spot => {
                // Spot uses cash account type and hedging OMS
                let account_type = AccountType::Cash;
                let oms_type = OmsType::Hedging;

                let core = ExecutionClientCore::new(
                    binance_config.trader_id,
                    ClientId::from(name),

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Pass a BinanceExecClientConfig instance to BinanceExecutionClientFactory.create.
  2. Inspect the {config:?} in the message to identify which type actually arrived.
  3. Guard generic wiring with a config_type() check before calling create.

Example fix

// before
let exec = BinanceExecutionClientFactory.create(name, &data_config, cache)?; // data config!

// after
let exec = BinanceExecutionClientFactory.create(name, &exec_config, cache)?; // BinanceExecClientConfig
Defensive patterns

Strategy: type-guard

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling BinanceExecutionClientFactory.create with a non-exec config object — swapped data/exec config arguments, or a generic harness that routes one config to both factories.

Common situations: Custom Rust wiring over the ExecutionClientFactory trait; integration tests that construct factories by hand; copy-pasted factory setup code where only the factory name was changed but not the config.

Related errors


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