nautechsystems/nautilus_trader · error
Failed to extract PyStrategy: {e}
Error message
Failed to extract PyStrategy: {e} What it means
Raised when the live node cannot extract a `PyRefMut<PyStrategy>` borrow from the Python strategy object during registration. This means the object registered as a strategy is not actually an instance of `PyStrategy` (or its Rust borrow cannot be taken, e.g. the object is already mutably borrowed in Python or is a different wrapper type). The registration aborts at this point.
Source
Thrown at crates/live/src/python/node.rs:1254
.node_mut()?
.kernel_mut()
.trader
.borrow_mut()
.prepare_python_strategy_instance(&strategy)
.map_err(to_pyruntime_err)?;
let (external_order_instrument_ids, oms_type) = Python::attach(
|py| -> anyhow::Result<(Option<Vec<InstrumentId>>, Option<OmsType>)> {
let bound = strategy.bind(py);
let config_obj = bound
.getattr("config")
.ok()
.filter(|config| !config.is_none());
let mut py_strategy_ref = bound
.extract::<PyRefMut<PyStrategy>>()
.map_err(Into::<PyErr>::into)
.map_err(|e| anyhow::anyhow!("Failed to extract PyStrategy: {e}"))?;
if let Some(config_obj) = config_obj.as_ref()
&& let Some(claims) =
extract_external_order_instrument_ids_config_attr(config_obj)?
{
py_strategy_ref.set_external_order_instrument_ids(Some(claims));
}
let claims = py_strategy_ref.external_order_instrument_ids();
let oms_type = config_obj
.as_ref()
.and_then(|cfg| cfg.getattr("oms_type").ok())
.filter(|value| !value.is_none())
.and_then(|value| value.extract::<OmsType>().ok());
Ok((claims, oms_type))
},
)View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the configured class subclasses `nautilus_trader.trading.strategy.Strategy` and is instantiated (not the class object itself).
- Check what `{e}` reports: a `TypeError`/`ExtractErr` means wrong type; a `BorrowMutError` means the object is already checked out.
- Ensure the factory/`create_config_instance` path returns the strategy instance directly.
- Do not hold the strategy object mutably in Python code (e.g. inside a callback) while registering it.
Example fix
# before
class MyActor(Actor): # wrong base, extract as PyStrategy fails
...
# after
from nautilus_trader.trading.strategy import Strategy
class MyStrategy(Strategy):
... Defensive patterns
Strategy: type-guard
Validate before calling
# Ensure the configured object is a Strategy instance before registration
from nautilus_trader.trading.strategy import Strategy
obj = strategy_module(**config_kwargs)
assert isinstance(obj, Strategy), f"expected Strategy, got {type(obj).__name__}" Type guard
def is_py_strategy(obj) -> bool:
from nautilus_trader.trading.strategy import Strategy
return isinstance(obj, Strategy) Try / catch
try:
node.trader.add_strategy(strategy)
except Exception as e:
if "Failed to extract PyStrategy" in str(e):
logging.error("object is not a PyStrategy (check base class/instantiation): %s", e)
else:
raise Prevention
- Subclass nautilus_trader.trading.strategy.Strategy (not Actor) for tradable strategies
- Pass an instantiated strategy object, never the class itself
- Ensure factory/config builders return the strategy instance directly
- Avoid holding the strategy object mutably in Python during registration
When it happens
Trigger: Registering a Python object as a strategy that is not a `PyStrategy` subclass instance (e.g. an Actor, a plain object, or a strategy built by a factory returning the wrong type), or extracting the borrow while the same object is already mutably borrowed elsewhere.
Common situations: Config `class_name` points to a class that subclasses `Actor` instead of `Strategy`; a custom factory wraps the strategy in a different container; passing the strategy class instead of an instance through a code path expecting a constructed `PyStrategy`.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Failed to extract PyStrategy: {e}
- Failed to downcast to PyStrategy: {e}
- Invalid `strategy_id` type
- Failed to convert historical data to Python: unsupported typ
- Failed to convert instrument to Python: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/07de7e4ef270a844.
Report an issue: GitHub.