nautechsystems/nautilus_trader · error

Invalid config type for PolymarketDataClientFactory. Expecte

Error message

Invalid config type for PolymarketDataClientFactory. Expected PolymarketDataClientConfig, was {config:?}

What it means

Raised in `PolymarketDataClientFactory::create` when the supplied config cannot be downcast to `PolymarketDataClientConfig`. The factory uses `config.as_any().downcast_ref::<PolymarketDataClientConfig>()` and errors if the caller passed an exec-client config (or any other concrete config type) to the data-client factory. The message includes the Debug representation of the unexpected config for diagnosis.

Source

Thrown at crates/adapters/polymarket/src/factories.rs:77

    feature = "python",
    pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.adapters.polymarket")
)]
#[derive(Debug, Clone)]
pub struct PolymarketDataClientFactory;

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

        Ok(Box::new(Self::create_client(name, polymarket_config)?))
    }

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

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

impl PolymarketDataClientFactory {
    fn create_client(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a PolymarketDataClientConfig to the data-client factory (and PolymarketExecClientConfig to the exec factory)
  2. Check the node/boot script for swapped factory-config pairings
  3. Inspect the printed config Debug output to see which type was actually passed

Example fix

// before
let data_client = data_factory.create(name, exec_config, ...)?;
// after
let data_client = data_factory.create(name, PolymarketDataClientConfig { .. }, ...)?;
Defensive patterns

Strategy: type-guard

Validate before calling

let ok = config.as_any().downcast_ref::<PolymarketDataClientConfig>().is_some();
if !ok { return Err(anyhow!("expected PolymarketDataClientConfig")); }

Type guard

fn as_data_config<'a>(cfg: &'a dyn AnyConfig) -> Option<&'a PolymarketDataClientConfig> {
    cfg.as_any().downcast_ref::<PolymarketDataClientConfig>()
}

Try / catch

match data_factory.create(name, config, clock).await {
    Err(e) if e.to_string().contains("Invalid config type for PolymarketDataClientFactory") => {
        // log which config type was passed (from the Debug in the message) and fix wiring
    }
    other => other,
}

Prevention

When it happens

Trigger: Registering/instantiating the data client factory with PolymarketExecClientConfig (or an unrelated config) instead of PolymarketDataClientConfig; wiring configs to factories in the wrong order in a node/trading setup script.

Common situations: Copy-paste mistakes when building both exec and data clients; YAML/JSON config parsed into the wrong concrete type; refactors renaming config structs so an old type still compiles but maps to the wrong factory.

Related errors


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