nautechsystems/nautilus_trader · error
Invalid config type for BetfairDataClientFactory. Expected B
Error message
Invalid config type for BetfairDataClientFactory. Expected BetfairDataClientConfig, was {config:?} What it means
BetfairDataClientFactory.create accepts any ClientConfig but only works with BetfairDataClientConfig. It downcasts the passed config; if the downcast fails it throws this error naming the expected and actual config types. Passing a config built for a different venue or client class triggers it.
Source
Thrown at crates/adapters/betfair/src/factories.rs:78
impl Default for BetfairDataClientFactory {
fn default() -> Self {
Self::new()
}
}
impl DataClientFactory for BetfairDataClientFactory {
fn create(
&self,
name: &str,
config: &dyn ClientConfig,
_cache: CacheView,
_clock: Rc<RefCell<dyn Clock>>,
) -> anyhow::Result<Box<dyn DataClient>> {
let betfair_config = config
.as_any()
.downcast_ref::<BetfairDataClientConfig>()
.ok_or_else(|| {
anyhow::anyhow!(
"Invalid config type for BetfairDataClientFactory. Expected BetfairDataClientConfig, was {config:?}",
)
})?
.clone();
betfair_config.validate()?;
let credential = betfair_config.credential()?;
let stream_config = betfair_config.stream_config();
let nav_filter = betfair_config.navigation_filter();
let currency = betfair_config.currency()?;
let min_notional = betfair_config.min_notional()?;
let http_client = BetfairHttpClient::new(
credential.clone(),
None,
None,
None,View on GitHub (pinned to 18893faf8b)
Solutions
- Construct the config as BetfairDataClientConfig for this factory.
- Check the factory registration/lookup so each factory receives its matching config type.
- If loading configs dynamically, verify the config's concrete type before calling create.
Example fix
// before config = BetfairExecutionClientConfig(...) client = BetfairDataClientFactory().create(..., config, ...) // after config = BetfairDataClientConfig(name=..., venue=..., api_key=..., username=..., password=...) client = BetfairDataClientFactory().create(..., config, ...)
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(config, BetfairDataClientConfig):
raise TypeError(f"BetfairDataClientFactory requires BetfairDataClientConfig, got {type(config).__name__}") Type guard
fn is_betfair_data_config(config: &dyn ClientConfig) -> bool {
config.as_any().downcast_ref::<BetfairDataClientConfig>().is_some()
} Try / catch
match factory.create(beneficiary, None, config, cache, clock) {
Ok(client) => client,
Err(e) if e.to_string().contains("Invalid config type") => {
panic!("wiring bug: wrong config for BetfairDataClientFactory: {e}")
}
Err(e) => return Err(e),
} Prevention
- Pair each factory with exactly its config type when registering.
- Use typed builders so the compiler enforces config/factory matching.
- Add a startup check that all node configs downcast to their factory's expected type.
When it happens
Trigger: Calling BetfairDataClientFactory.create with a config that is not BetfairDataClientConfig — e.g. a BetfairExecutionClientConfig, another venue's DataClientConfig, or a generic config.
Common situations: Mixing up data vs execution config types when wiring clients in a node/script; copy-pasted factory registration with the wrong config class; dynamic config loading that yields the wrong concrete type.
Related errors
- Invalid config type for BinanceExecutionClientFactory. Expec
- Invalid config type for BetfairExecutionClientFactory. Expec
- Invalid config type for BetfairDataClientFactory. Expected B
- Invalid config type for BetfairExecutionClientFactory. Expec
- Invalid config type for BitmexDataClientFactory. Expected Bi
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8597d92ec5b53c6d.
Report an issue: GitHub.