nautechsystems/nautilus_trader · error

Invalid config type for TardisDataClientFactory. Expected Ta

Error message

Invalid config type for TardisDataClientFactory. Expected TardisDataClientConfig, was {config:?}

What it means

Raised in TardisDataClientFactory::create when the passed config object cannot be downcast to TardisDataClientConfig. The factory was given a config type built for a different adapter, indicating a factory/config mismatch in client registration.

Source

Thrown at crates/adapters/tardis/src/factories.rs:74

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

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

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

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

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

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a TardisDataClientConfig to TardisDataClientFactory; check which factory is paired with each config.
  2. Verify the config was constructed with the Tardis adapter's builder, not another adapter's.
  3. Check that you're not iterating a shared config list against a single factory.
  4. After an adapter version upgrade, rebuild configs with the matching adapter version.

Example fix

// before
let data_client = tardis_factory.create(binance_config, ...)?;
// after
let data_client = tardis_factory.create(tardis_data_config, ...)?;
Defensive patterns

Strategy: type-guard

Validate before calling

// Match each config to its factory by name before create
anyhow::ensure!(
    config.as_any().is::<TardisDataClientConfig>(),
    "pass TardisDataClientConfig to TardisDataClientFactory"
);

Type guard

fn is_tardis_config(config: &dyn UserConfig) -> bool {
    config.as_any().downcast_ref::<TardisDataClientConfig>().is_some()
}

Try / catch

let client = factory.create(config, ...)
    .map_err(|e| if e.to_string().contains("Invalid config type for TardisDataClientFactory") {
        anyhow::anyhow!("factory/config mispairing: {e}")
    } else { e })?;

Prevention

When it happens

Trigger: Calling create with a config whose as_any().downcast_ref::<TardisDataClientConfig>() returns None — e.g. a BinanceDataClientConfig or any other client config passed to this factory.

Common situations: Registering factories and configs in the wrong order; a typo pairing the wrong factory with a config; building clients from a mixed config list; using an older config struct after an adapter refactor.

Related errors


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