nautechsystems/nautilus_trader · error
DataActor {} must be registered before calling `clock_ref()`
Error message
DataActor {} must be registered before calling `clock_ref()` - trader_id: {:?} What it means
`DataActor::clock_ref()` panics when the actor's clock handle is `None`, meaning the actor was never registered with a trader (registration injects the clock). Borrowing the clock before registration breaks the actor lifecycle contract.
Source
Thrown at crates/common/src/actor/data_actor.rs:4098
pub fn timestamp_ns(&self) -> UnixNanos {
self.clock_ref().timestamp_ns()
}
pub(super) fn clock_api(&self) -> ClockApi<'_> {
let clock = self.clock.as_ref().unwrap_or_else(|| {
panic!(
"DataActor {} must be registered before calling `clock()` - trader_id: {:?}",
self.actor_id, self.trader_id
)
});
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.View on GitHub (pinned to 18893faf8b)
Solutions
- Register the actor with a trader before any clock access.
- Move clock access to post-registration lifecycle hooks (`on_start`, handlers).
- In tests, run actors through the registered test harness.
Example fix
// before let actor = MyActor::new(); let now = actor.clock_ref().timestamp_ns(); // panic // after trader.add_actor(MyActor::new()); // access clock inside on_start via self.clock_ref()
Defensive patterns
Strategy: type-guard
Validate before calling
assert!(actor.is_registered(), "clock_ref() requires trader registration");
Type guard
fn clock_available(actor: &DataActor) -> bool { actor.is_registered() } Prevention
- Call clock-dependent logic only from registered lifecycle hooks
- In unit tests, use the project's registered actor harness
- Avoid exposing raw clock_ref() calls in strategy code paths
When it happens
Trigger: Any read access to the clock via `clock_ref()` on an unregistered `DataActor` (e.g. inside `timestamp_ns()` or custom code calling `clock_ref()` directly).
Common situations: Calling clock-dependent logic during `on_init`/construction; actors used standalone in unit tests without a trader; forgetting `trader.add_actor(...)` before a manual run.
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 calling `clock()` - t
- DataActor {} must be registered before calling `clock_mut()`
- DataActor {} must be registered before calling `cache()` - t
- Cannot add actor while node is running, add actors before ru
- DataActor must be registered before accessing clock
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9e905c9f7beeed18.
Report an issue: GitHub.