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
- Read the Debug output in the message to see which config type was actually passed
- Ensure the config passed to the factory is created via SandboxExecutionClientConfig / its builder
- Fix the factory-to-config pairing in your registration code (use SandboxExecutionClientFactory only with SandboxExecutionClientConfig)
- 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
- Pair each factory with its exact config type in registration code
- Build configs via the matching *Config builder
- Check the Debug name in the error to spot the wrong type immediately
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
- Invalid config type for BinanceDataClientFactory. Expected B
- Invalid config type for CoinbaseDataClientFactory. Expected
- Invalid config type for CoinbaseExecutionClientFactory. Expe
- Invalid config type for DeriveDataClientFactory. Expected De
- Invalid config type for DydxDataClientFactory. Expected Dydx
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e65c42c32c6f8ea5.
Report an issue: GitHub.