nautechsystems/nautilus_trader · error
Failed to register PyDataActor: {e}
Error message
Failed to register PyDataActor: {e} What it means
NautilusTrader throws this when a Python actor object implementing the PyDataActor trait fails during its `register(trader_id, clock, cache)` call while being attached to a trader. The actor's own registration logic (e.g. subscribing, state transitions) raised a Python error, which is wrapped in an anyhow error. It means the actor could not be fully initialized inside the trading system.
Source
Thrown at crates/system/src/python/registration.rs:434
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>()
.map_err(|e| anyhow::anyhow!("Failed to downcast to PyDataActor: {e}"))?;
py_data_actor_ref.borrow().register_in_global_registries()?;
Ok(())
})View on GitHub (pinned to 18893faf8b)
Solutions
- Read the chained `{e}` message to find the underlying Python exception and fix the actor code that raised it
- Verify all actor config values are valid before adding the actor to the trader
- Confirm any clients/adapters the actor's subscriptions depend on are registered before the actor
- Run the actor registration in isolation with logging enabled to pinpoint the failing hook
Example fix
// before: actor with bad config raises inside register
trader.add_actor(MyActor(config=MyActorConfig(instrument_id="INVALID")))
// after: validate first
instrument_id = InstrumentId.from_str("BTCUSDT.BINANCE") # raises early if bad
trader.add_actor(MyActor(config=MyActorConfig(instrument_id=instrument_id))) Defensive patterns
Strategy: try-catch
Validate before calling
# before adding actor assert isinstance(actor, Actor), "actor must subclass nautilus_trader Actor" actor.validate_config() # or validate config fields manually
Type guard
def is_valid_actor(obj) -> bool:
from nautilus_trader.common.actor import Actor
return isinstance(obj, Actor) Try / catch
try:
trader.add_data_actor(actor)
except Exception as e:
logging.exception("actor registration failed: %s", e)
raise Prevention
- Validate actor config fields before registering
- Register required clients/adapters before actors that depend on them
- Test actors standalone in a backtest node before live use
When it happens
Trigger: Calling `trader.add_data_actor(actor)` (or adding an actor via a node config) where the actor's `register()` — or any code it calls such as `subscribe_*` in on_start registration paths — raises a Python exception. Any Python-side error inside the actor during registration surfaces as this message.
Common situations: Actor constructors or registration hooks referencing unavailable config, importing modules that are missing, misconfigured subscription parameters (invalid instrument IDs, client IDs), or bugs in custom actor code that run during registration.
Related errors
- Failed to downcast to PyDataActor: {e}
- Invalid `external_order_claims` type: {e}
- Invalid `external_order_claims` instrument ID {claim}: {e}
- run_config_id is required when a BacktestNode is provided
- BacktestNode state is unavailable when dispose_on_completion
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a4b0985e28064786.
Report an issue: GitHub.