nautechsystems/nautilus_trader · error · anyhow::Error

Invalid config type for DatabentoDataClientFactory. Expected

Error message

Invalid config type for DatabentoDataClientFactory. Expected DatabentoDataClientConfig, was {config:?}

What it means

DatabentoDataClientFactory::create receives a generic config object and downcasts it to DatabentoDataClientConfig. If the caller passed a different config type (any other client's config or a plain config), the downcast fails and this error names both the expected type and the actual config's debug representation.

Source

Thrown at crates/adapters/databento/src/factories.rs:120

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

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

        let client_id = ClientId::from(name);
        let client =
            DatabentoDataClient::new(client_id, databento_config, get_atomic_clock_realtime())?;
        Ok(Box::new(client))
    }

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

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

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the config passed to the Databento factory is constructed via DatabentoDataClientConfig (or its builder)
  2. Check that each adapter's factory is paired with its matching config type in the node config
  3. Print the config's debug output (included in the error) to identify the actual type passed
  4. Fix client-name to config mapping in the trading node configuration

Example fix

// before
let client = data_factory.create("Databento", &base_data_client_config, &logger, &clock)?;
// after
let cfg = DatabentoDataClientConfig::builder().api_key(key)?.publishers_filepath(path)?.build()?;
let client = data_factory.create("Databento", &cfg, &logger, &clock)?;
Defensive patterns

Strategy: type-guard

Validate before calling

// Rust
cfg.as_any().downcast_ref::<DatabentoDataClientConfig>().is_some()

Try / catch

// Rust
Err(e) => error!("wrong config: {e:#}"),

Prevention

When it happens

Trigger: Calling DataClientFactory.create (or get_data_client through the client registration machinery) with a config that is not a DatabentoDataClientConfig — e.g. passing DatabentoExecClientConfig, another venue's DataClientConfig, or a constructed base config.

Common situations: Wiring a trading node where the config map is keyed by client name but the config objects are mismatched; copy-pasted factory registration with the wrong config type; programmatic client building mixing adapter configs.

Related errors


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