nautechsystems/nautilus_trader · error
BacktestEngineConfig.controller for importable controller '{
Error message
BacktestEngineConfig.controller for importable controller '{}' requires the python feature What it means
BacktestEngineConfig supports an importable Python controller, but wiring one requires the crate's `python` feature. When the engine is built without Python bindings and a controller is configured, construction fails with this error instead of silently ignoring the controller.
Source
Thrown at crates/backtest/src/engine.rs:155
///
/// # Errors
///
/// Returns an error if the core `NautilusKernel` fails to initialize.
pub fn new(mut config: BacktestEngineConfig) -> anyhow::Result<Self> {
// The engine does not replay `add_instrument` on reset, so reruns rely
// on the cache retaining instruments regardless of the caller's config.
let mut cache_config = config.cache.unwrap_or_default();
cache_config.drop_instruments_on_reset = false;
config.cache = Some(cache_config);
let kernel = NautilusKernel::new("BacktestEngine".to_string(), config.clone())?;
let instance_id = kernel.instance_id;
#[cfg(feature = "python")]
if let Some(controller) = config.controller.as_ref() {
Trader::add_controller_from_importable_config(&kernel.trader, controller)?;
}
#[cfg(not(feature = "python"))]
if let Some(controller) = config.controller.as_ref() {
anyhow::bail!(
"BacktestEngineConfig.controller for importable controller '{}' requires the python feature",
controller.controller_path
);
}
Ok(Self {
kernel,
instance_id,
config,
accumulator: TimeEventAccumulator::new(),
run_config_id: None,
run_id: None,
venues: IndexMap::new(),
exec_clients: Vec::new(),
has_data: AHashSet::new(),
has_book_data: AHashSet::new(),
has_book_processed: AHashSet::new(),
data_iterator: BacktestDataIterator::new(),View on GitHub (pinned to 18893faf8b)
Solutions
- Rebuild with the python feature enabled (e.g. `cargo build --features python`)
- Remove `controller` from the BacktestEngineConfig for Rust-only builds
- Conditionally set the controller in config loading based on build features
- Use a Rust-native controller implementation if available instead of the importable Python one
Example fix
// before let engine = BacktestEngine::new(Some(config_with_controller), None)?; // no python feature // after cargo build --features python // or remove the controller: config.controller = None;
Defensive patterns
Strategy: validation
Validate before calling
#[cfg(not(feature = "python"))]
if config.controller.is_some() {
panic!("controller configured but built without the python feature");
} Try / catch
let engine = BacktestEngine::new(Some(config), None)
.map_err(|e| if e.to_string().contains("requires the python feature") {
anyhow::anyhow!("Rebuild with --features python or drop config.controller")
} else { e })?; Prevention
- Keep controller settings out of shared configs used by Rust-only builds
- Document feature requirements next to config fields
- Verify feature flags in build scripts/CI matrices
When it happens
Trigger: Constructing a BacktestEngine with config.controller set to Some(ImportableControllerConfig{..}) while the nautilus crate was compiled without the `python` feature (e.g. a pure-Rust build).
Common situations: Using a config file generated from a Python environment in a Rust-only binary; enabling the controller field by default in shared config tooling; a build without `--features python`.
Related errors
- Failed to import module {module_name}: {e}
- Failed to get class {class_name}: {e}
- Failed to import config module {config_module_name}: {e}
- Failed to get config class {config_class_name}: {e}
- Invalid `external_order_claims` type: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2412d1adccca3854.
Report an issue: GitHub.