nautechsystems/nautilus_trader · error
LiveNode.add_exec_algorithm requires a Python v2 ExecutionAl
Error message
LiveNode.add_exec_algorithm requires a Python v2 ExecutionAlgorithm instance; use add_exec_algorithm_from_config for DataActor-based algorithms: {e} What it means
Raised by LiveNode.add_exec_algorithm when the supplied object cannot be extracted as a native PyExecutionAlgorithm (v2 Python execution algorithm). The message itself points to the remedy: DataActor-based (pure-Python actor) algorithms must be added via add_exec_algorithm_from_config instead.
Source
Thrown at crates/live/src/python/node.rs:1466
return Err(to_pyruntime_err(
"Cannot add exec algorithm while node is running, add exec algorithms before running the node",
));
}
log::debug!("`add_exec_algorithm` with a constructed instance");
let exec_algorithm = exec_algorithm.clone().unbind();
let py_exec_algorithm = Python::attach(|py| -> anyhow::Result<PyExecutionAlgorithm> {
let bound = exec_algorithm.bind(py);
let config = bound
.getattr("config")
.ok()
.filter(|config| !config.is_none());
let mut py_exec_algorithm_ref = bound
.extract::<PyRefMut<PyExecutionAlgorithm>>()
.map_err(Into::<PyErr>::into)
.map_err(|e| {
anyhow::anyhow!(
"LiveNode.add_exec_algorithm requires a Python v2 ExecutionAlgorithm instance; use add_exec_algorithm_from_config for DataActor-based algorithms: {e}"
)
})?;
if let Some(config) = config.as_ref() {
py_exec_algorithm_ref.configure_from_py_config(config)?;
}
py_exec_algorithm_ref.set_python_instance(bound)?;
Ok(py_exec_algorithm_ref.clone())
})
.map_err(to_pyruntime_err)?;
let exec_algorithm_id = self
.node_mut()?
.kernel_mut()
.trader
.borrow_mut()View on GitHub (pinned to 18893faf8b)
Solutions
- If the algorithm is DataActor-based, switch the call to add_exec_algorithm_from_config with its config
- If it should be a v2 instance, ensure the class subclasses nautilus_trader's ExecutionAlgorithm
- Check import paths — nautilus_trader.execution.algorithm vs custom modules
- Use the config path end-to-end for consistency
Example fix
// before node.add_exec_algorithm(MyDataActorBasedAlgo(config)) // after node.add_exec_algorithm_from_config(MyExecAlgoConfig(...))
Defensive patterns
Strategy: validation
Validate before calling
from nautilus_trader.execution.algorithm import ExecutionAlgorithm assert isinstance(algo, ExecutionAlgorithm), "use add_exec_algorithm_from_config for DataActor-based algos"
Type guard
def is_v2_exec_algorithm(obj) -> bool:
from nautilus_trader.execution.algorithm import ExecutionAlgorithm
return isinstance(obj, ExecutionAlgorithm) Try / catch
try:
node.add_exec_algorithm(algo)
except Exception as e:
if "requires a Python v2 ExecutionAlgorithm" in str(e):
node.add_exec_algorithm_from_config(algo.config)
else:
raise Prevention
- Route DataActor-based algorithms to add_exec_algorithm_from_config
- Keep one registration convention per node config
- Check base classes when migrating from the pure-Python engine
When it happens
Trigger: Calling add_exec_algorithm with an object that is not a v2 pyo3-backed ExecutionAlgorithm instance — e.g. a DataActor/exec-actor subclass built from config, or a custom class not deriving from nautilus_trader.ExecutionAlgorithm.
Common situations: Mixing the two registration APIs after refactor; passing an algorithm built with a config object to the instance-based API; porting strategies from the pure-Python engine.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Failed to extract PyDataActor: {e}
- Python on_order failed: {e}
- Data client '{name}' is already registered
- Execution client '{name}' is already registered
- Cannot modify order in place: status is {status:?}, expected
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5bf9e909595ea491.
Report an issue: GitHub.