nautechsystems/nautilus_trader · error
Invalid config type for BetfairDataClientFactory. Expected B
Error message
Invalid config type for BetfairDataClientFactory. Expected BetfairDataConfig, was {config:?} What it means
BetfairDataClientFactory::create tried to downcast the passed &dyn ClientConfig to BetfairDataConfig and failed — the config object is a different concrete type. This is a bootstrap/wiring error: the TradingNode or custom client setup is constructing the Betfair data client with a config that is not the Betfair-specific one, so creation aborts before any connection is made.
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::<BetfairDataConfig>()
.ok_or_else(|| {
anyhow::anyhow!(
"Invalid config type for BetfairDataClientFactory. Expected BetfairDataConfig, 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 a4b06ed870)
Solutions
- Ensure the config-map entry routed to BetfairDataClientFactory is a BetfairDataConfig instance.
- When building clients manually, downcast-check the config before calling create and construct the matching type.
- Review the factory-to-config pairing in the TradingNode/routing configuration.
Example fix
// before: map pairs data factory with exec config
config_map.insert("BETFAIR".to_string(), Box::new(BetfairExecConfig::default()));
// after
config_map.insert("BETFAIR".to_string(), Box::new(BetfairDataConfig::default())); Defensive patterns
Strategy: type-guard
Validate before calling
let is_valid = config
.as_any()
.downcast_ref::<BetfairDataConfig>()
.is_some();
if !is_valid {
return Err(anyhow::anyhow!("expected BetfairDataConfig for data factory"));
} Type guard
fn is_betfair_data_config(config: &dyn ClientConfig) -> bool {
config.as_any().downcast_ref::<BetfairDataConfig>().is_some()
} Prevention
- Keep venue config maps colocated with factory registrations so pairings are reviewable in one place.
- Add a startup smoke test that creates each client factory with its config to catch wiring errors early.
- Never share one config instance between data and exec factories.
When it happens
Trigger: Registering BetfairDataClientFactory in a config map whose entry provides a different config type (e.g. BetfairExecConfig or another venue's config); custom bootstraps that build factories generically and pass the wrong config instance.
Common situations: Copy-paste errors in a broker/venue config map pairing the data factory with the wrong config struct; manual client construction mixing data and exec config types.
Related errors
- Invalid config type for BetfairExecutionClientFactory. Expec
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
- pandas is required for visualization; install it with `pip i
- {name} must not be None
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/ba4051c499fdc3dc.
Report an issue: GitHub.