nautechsystems/nautilus_trader · error
DataActor {} must be registered before calling `cache()` - t
Error message
DataActor {} must be registered before calling `cache()` - trader_id: {:?} What it means
`DataActor::cache_api()` panics when the actor's cache handle is `None`, i.e. the actor was not registered with a trader that injects the cache. Any cache access on an unregistered actor violates the lifecycle contract and panics.
Source
Thrown at crates/common/src/actor/data_actor.rs:4108
});
ClockApi::new(clock.as_ref())
}
fn clock_ref(&self) -> Ref<'_, dyn Clock> {
self.clock
.as_ref()
.unwrap_or_else(|| {
panic!(
"DataActor {} must be registered before calling `clock_ref()` - trader_id: {:?}",
self.actor_id, self.trader_id
)
})
.borrow()
}
fn cache_api(&self) -> CacheApi<'_> {
let cache = self.cache.as_ref().unwrap_or_else(|| {
panic!(
"DataActor {} must be registered before calling `cache()` - trader_id: {:?}",
self.actor_id, self.trader_id
)
});
CacheApi::new(cache.as_ref())
}
/// Register the data actor with a trader.
///
/// # Errors
///
/// Returns an error if the actor has already been registered with a trader
/// or if the provided dependencies are invalid.
pub fn register(
&mut self,
trader_id: TraderId,
clock: Rc<RefCell<dyn Clock>>,
cache: Rc<RefCell<Cache>>,View on GitHub (pinned to 18893faf8b)
Solutions
- Register the actor with a trader/node so the cache is injected.
- Move cache access into `on_start` or event handlers that run post-registration.
- If the actor needs cache data at construction, pass it explicitly instead of reading the injected cache.
Example fix
// before
let actor = MyActor::new();
let order = actor.cache_api().order(&client_order_id); // panic
// after
impl DataActor for MyActor {
fn on_start(&mut self) {
let order = self.cache_api().order(&self.client_order_id);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if actor.is_registered() {
let order = actor.cache_api().order(&client_order_id);
} Type guard
fn cache_available(actor: &DataActor) -> bool { actor.is_registered() } Prevention
- Access the cache only inside on_start/handler methods
- Pass construction-time data explicitly rather than reading the injected cache early
- In tests, register actors with a stub trader/cache before calling cache accessors
When it happens
Trigger: Calling `cache_api()`/cache accessors (e.g. `cache_order`, instrument lookups) before the actor is registered with a trader.
Common situations: Querying the cache in the actor constructor or before `on_start`; standalone actors in tests without registration; actors added to a node but accessed from another thread/context before registration completes.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- DataActor must be registered before accessing cache
- DataActor {} must be registered before calling `clock_mut()`
- DataActor {} must be registered before calling `clock()` - t
- DataActor {} must be registered before calling `clock_ref()`
- Cannot add actor while node is running, add actors before ru
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4a84a54c8c2ffb84.
Report an issue: GitHub.