nautechsystems/nautilus_trader · error

Controller must inherit from `nautilus_trader.trading.Contro

Error message

Controller must inherit from `nautilus_trader.trading.Controller`: {e}

What it means

`bind_controller_trader` extracts the passed Python controller object into `PyRefMut<PyController>`. PyO3's `extract` only succeeds if the Python object's class actually inherits from `nautilus_trader.trading.Controller` (the Rust-exposed base). Any other object raises this error.

Source

Thrown at crates/system/src/python/controller.rs:209

    }

    #[pyo3(name = "remove_strategy_from_id")]
    fn py_remove_strategy_from_id(slf: PyRef<'_, Self>, strategy_id: StrategyId) -> PyResult<()> {
        Self::py_remove_strategy(slf, strategy_id)
    }
}

/// Binds the registered trader to a user-authored Python controller instance.
pub(crate) fn bind_controller_trader(
    python_controller: &Py<PyAny>,
    trader: &Rc<RefCell<Trader>>,
) -> anyhow::Result<()> {
    Python::attach(|py| -> anyhow::Result<()> {
        let mut controller = python_controller
            .bind(py)
            .extract::<PyRefMut<PyController>>()
            .map_err(|e| {
                anyhow::anyhow!(
                    "Controller must inherit from `nautilus_trader.trading.Controller`: {e}"
                )
            })?;

        controller.bind_trader(trader);

        Ok(())
    })
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Make the controller class inherit from `nautilus_trader.trading.Controller`.
  2. Ensure you pass the controller instance (not its config or class) to the binding API.
  3. Check that the installed nautilus_trader package exposes the same Controller base the Rust binding expects (matching versions).

Example fix

// before
class MyController:
    def stop(self): ...

// after
from nautilus_trader.trading import Controller

class MyController(Controller):
    def stop(self): ...
Defensive patterns

Strategy: type-guard

Validate before calling

from nautilus_trader.trading import Controller
assert isinstance(my_controller, Controller), "controller must subclass Controller"

Type guard

def is_controller(obj) -> bool:
    from nautilus_trader.trading import Controller
    return isinstance(obj, Controller)

Try / catch

try:
    bind_controller_trader(controller, trader)
except Exception as e:
    if "must inherit" in str(e):
        raise TypeError(f"{type(controller).__name__} must subclass nautilus_trader.trading.Controller") from e
    raise

Prevention

When it happens

Trigger: Passing a Python object to the controller binding API whose class does not subclass `nautilus_trader.trading.Controller` — e.g. a custom controller implementing the methods duck-typed but without inheriting the base class, or a None/mistyped argument.

Common situations: Writing a custom live controller and forgetting `from nautilus_trader.trading import Controller` inheritance; passing a config object instead of the controller instance; typos importing a different Controller class.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a4936ac6ef965f1b. Report an issue: GitHub.