nautechsystems/nautilus_trader · error · anyhow::Error

Invalid config type for SandboxExecutionClientFactory. Expec

Error message

Invalid config type for SandboxExecutionClientFactory. Expected SandboxExecutionClientConfig, was {config:?}

What it means

SandboxExecutionClientFactory.create receives a generic config object and downcasts it to SandboxExecutionClientConfig. If the registered config is any other type (wrong factory for the config, or config built from the wrong builder), the downcast fails and this error names the actual config received via Debug formatting.

Source

Thrown at crates/adapters/sandbox/src/factory.rs:74

    #[must_use]
    pub const fn new() -> Self {
        Self
    }
}

impl SimulatedExecutionClientFactory for SandboxExecutionClientFactory {
    fn create(
        &self,
        trader_id: TraderId,
        name: &str,
        config: &dyn ClientConfig,
        cache: Rc<RefCell<Cache>>,
    ) -> anyhow::Result<Box<dyn ExecutionClient>> {
        let sandbox_config = config
            .as_any()
            .downcast_ref::<SandboxExecutionClientConfig>()
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "Invalid config type for SandboxExecutionClientFactory. Expected SandboxExecutionClientConfig, was {config:?}",
                )
            })?
            .clone();

        let client_id = ClientId::from(name);
        let clock: Rc<RefCell<dyn Clock>> = Rc::new(RefCell::new(LiveClock::default()));

        let core = ExecutionClientCore::new(
            trader_id,
            client_id,
            sandbox_config.venue,
            sandbox_config.oms_type,
            sandbox_config.account_id,
            sandbox_config.account_type,
            sandbox_config.base_currency,
            cache.clone(),
        );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the Debug output in the message to see which config type was actually passed
  2. Ensure the config passed to the factory is created via SandboxExecutionClientConfig / its builder
  3. Fix the factory-to-config pairing in your registration code (use SandboxExecutionClientFactory only with SandboxExecutionClientConfig)
  4. Check for typos between similar sandbox config types if multiple exist

Example fix

// before: wrong config type for the factory
let config = LiveExecutionClientConfig::new(...);
let client = SandboxExecutionClientFactory.create(name, config, ...);
// after
let config = SandboxExecutionClientConfig::new(...);
let client = SandboxExecutionClientFactory.create(name, config, ...);
Defensive patterns

Strategy: type-guard

Type guard

fn is_sandbox_config(config: &dyn ExecutionClientConfig) -> bool {
    config.as_any().downcast_ref::<SandboxExecutionClientConfig>().is_some()
}

Try / catch

let client = match factory.create(name, config, cache) {
    Ok(c) => c,
    Err(e) if e.to_string().contains("Invalid config type") => {
        panic!("config/factory mismatch: {e}") // fix registration, don't retry
    }
    Err(e) => return Err(e.into()),
};

Prevention

When it happens

Trigger: Registering SandboxExecutionClientFactory with an ExecutionClientConfig of a different concrete type — e.g. passing LiveExecutionClientConfig, BacktestExecutionClientConfig, or a hand-built config struct into the factory's create().

Common situations: Copy-pasted factory registration in client setup code pairing the wrong factory with a config; programmatic node assembly where builders were mixed up; renaming/refactors that changed config types.

Related errors


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