nautechsystems/nautilus_trader · error
DataActor {} must be registered before calling `clock()` - t
Error message
DataActor {} must be registered before calling `clock()` - trader_id: {:?} What it means
`DataActor::clock_api()` panics if the actor's clock handle is `None`, i.e. the actor has not been registered with a trader that injects the clock. Accessing clock-based APIs like `timestamp_ns()` on an unregistered actor is invalid lifecycle usage.
Source
Thrown at crates/common/src/actor/data_actor.rs:4086
}
/// Returns the actors ID.
pub fn actor_id(&self) -> ActorId {
self.actor_id
}
fn default_actor_id() -> ActorId {
ActorId::from(stringify!(DataActor))
}
/// Returns a UNIX nanoseconds timestamp from the actor's internal clock.
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()
}View on GitHub (pinned to 18893faf8b)
Solutions
- Register the actor with a trader/node so the clock is injected.
- Defer time-dependent calls to `on_start` or later lifecycle hooks.
- For test scenarios, register the actor with a test clock rather than calling accessors on an unregistered actor.
Example fix
// before let mut actor = MyActor::new(); let ts = actor.timestamp_ns(); // panic: not registered // after let mut actor = MyActor::new(); trader.add_actor(actor); // within on_start: self.timestamp_ns() is valid
Defensive patterns
Strategy: type-guard
Validate before calling
if !actor.is_registered() {
eprintln!("timestamp_ns() requires a registered actor");
return;
} Type guard
fn has_clock(actor: &DataActor) -> bool { actor.is_registered() } Prevention
- Gate all time queries behind on_start or later hooks
- Register actors before manually invoking their accessors in tests
- Never cache clock references across registration boundaries
When it happens
Trigger: Calling `timestamp_ns()`/`clock_api()` (which routes through the clock) before the actor is registered with a trader.
Common situations: Standalone actors used without a trader; clock access during construction or before `on_start`; test harnesses that instantiate `DataActor` without registering it.
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_ref()`
- 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/1a0fbca8eb2273c8.
Report an issue: GitHub.