nautechsystems/nautilus_trader · error

Invalid config type for DeriveDataClientFactory. Expected De

Error message

Invalid config type for DeriveDataClientFactory. Expected DeriveDataClientConfig, was {config:?}

What it means

DeriveDataClientFactory::create downcasts the generic config to DeriveDataClientConfig. If the supplied config is any other type, the downcast fails and the factory raises this error, echoing the debug representation of the wrong config. Factories are type-safe dispatchers: the Derive data factory only builds clients from Derive data configs.

Source

Thrown at crates/adapters/derive/src/factories.rs:88

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

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

        let client = DeriveDataClient::new(ClientId::from(name), derive_config)?;
        Ok(Box::new(client))
    }

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

    fn config_type(&self) -> &'static str {
        stringify!(DeriveDataClientConfig)
    }
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a DeriveDataClientConfig instance to DeriveDataClientFactory; check the config type in the error's {config:?} output.
  2. Fix the factory-to-config pairing in your node wiring so each factory gets its own config type.
  3. If building configs from TOML/JSON, ensure the config section deserializes into DeriveDataClientConfig.
  4. Verify you are not confusing DeriveDataClientFactory with DeriveExecClientFactory (which expects the exec config).

Example fix

// before
factory.create(name, DeriveExecClientConfig { .. })?; // wrong config type
// after
factory.create(name, DeriveDataClientConfig { .. })?;
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_derive_data_config(cfg: &dyn AnyConfigLike) -> bool {
    cfg.as_any().downcast_ref::<DeriveDataClientConfig>().is_some()
}

Type guard

fn as_derive_data_config(cfg: &dyn ClientConfig) -> Option<&DeriveDataClientConfig> {
    cfg.as_any().downcast_ref::<DeriveDataClientConfig>()
}

Try / catch

match factory.create(name, config) {
    Ok(client) => /* use client */,
    Err(e) if e.to_string().contains("Invalid config type") => {
        // inspect {config:?} in the message and fix the factory/config pairing
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Registering or invoking DeriveDataClientFactory with a config object of another adapter's type (e.g. a Binance or DeriveExecClientConfig), or with a plain/placeholder config struct.

Common situations: Wiring clients in a live node where factory/config pairs got mismatched; copy-pasted factory registration code; passing an execution config where a data config is expected.

Related errors


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