nautechsystems/nautilus_trader · error

Failed to extract PyDataActor: {e}

Error message

Failed to extract PyDataActor: {e}

What it means

`register_python_data_actor` extracts the actor as `PyRefMut<PyDataActor>` to register it with trader_id, clock, and cache. PyO3 extraction fails unless the Python object inherits the Rust-backed Actor base (`nautilus_trader.common.actor.Actor`), producing this error.

Source

Thrown at crates/system/src/python/registration.rs:430

    }

    /// Gives `actor` its component clock and registers it in the global component, actor, and
    /// wrapper registries.
    fn register_python_data_actor(
        &mut self,
        actor: &Py<PyAny>,
        component_id: ComponentId,
    ) -> anyhow::Result<()> {
        let clock = self.create_component_clock(component_id);
        let trader_id = self.trader_id;
        let cache = self.cache.clone();

        Python::attach(|py| -> anyhow::Result<()> {
            let py_actor = actor.bind(py);
            let mut py_data_actor_ref = py_actor
                .extract::<PyRefMut<PyDataActor>>()
                .map_err(Into::<PyErr>::into)
                .map_err(|e| anyhow::anyhow!("Failed to extract PyDataActor: {e}"))?;

            py_data_actor_ref
                .register(trader_id, clock, cache)
                .map_err(|e| anyhow::anyhow!("Failed to register PyDataActor: {e}"))?;

            log::debug!(
                "Internal PyDataActor registered: {}, state: {:?}",
                py_data_actor_ref.is_registered(),
                py_data_actor_ref.state()
            );

            Ok(())
        })?;

        Python::attach(|py| -> anyhow::Result<()> {
            let py_actor = actor.bind(py);
            let py_data_actor_ref = py_actor
                .cast::<PyDataActor>()

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Make the actor class inherit from `nautilus_trader.common.actor.Actor` (or the appropriate Strategy base for exec algorithms).
  2. Pass the instantiated actor object, not the class or its config.
  3. Align the actor's defining module with the active nautilus_trader installation (single version).

Example fix

// before
class MyActor:
    def on_start(self): ...

// after
from nautilus_trader.common.actor import Actor

class MyActor(Actor):
    def on_start(self): ...
Defensive patterns

Strategy: type-guard

Validate before calling

from nautilus_trader.common.actor import Actor
assert isinstance(my_actor, Actor), "actor must subclass Actor"

Type guard

def is_actor(obj) -> bool:
    from nautilus_trader.common.actor import Actor
    return isinstance(obj, Actor)

Try / catch

try:
    trader.add_actor(actor)
except Exception as e:
    if "Failed to extract PyDataActor" in str(e):
        raise TypeError(f"{type(actor).__name__} must subclass nautilus_trader Actor") from e
    raise

Prevention

When it happens

Trigger: Calling add_actor / add_exec_algorithm with a Python object whose class does not subclass the nautilus_trader `Actor` base — e.g. a plain class implementing callbacks, or an exec algorithm not built on Actor/Strategy bases.

Common situations: Custom data actors forgetting to inherit `Actor`; passing actor config instead of the actor instance; mixing actor classes from a different nautilus_trader build.

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/2737ba8787a58732. Report an issue: GitHub.