{"record":{"id":"9e905c9f7beeed18","repo":"nautechsystems/nautilus_trader","slug":"dataactor-must-be-registered-before-calling-cl-9e905c","errorCode":null,"errorMessage":"DataActor {} must be registered before calling `clock_ref()` - trader_id: {:?}","messagePattern":"DataActor (.+?) must be registered before calling `clock_ref\\(\\)` - trader_id: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/actor/data_actor.rs","lineNumber":4098,"sourceCode":"    pub fn timestamp_ns(&self) -> UnixNanos {\n        self.clock_ref().timestamp_ns()\n    }\n\n    pub(super) fn clock_api(&self) -> ClockApi<'_> {\n        let clock = self.clock.as_ref().unwrap_or_else(|| {\n            panic!(\n                \"DataActor {} must be registered before calling `clock()` - trader_id: {:?}\",\n                self.actor_id, self.trader_id\n            )\n        });\n        ClockApi::new(clock.as_ref())\n    }\n\n    fn clock_ref(&self) -> Ref<'_, dyn Clock> {\n        self.clock\n            .as_ref()\n            .unwrap_or_else(|| {\n                panic!(\n                    \"DataActor {} must be registered before calling `clock_ref()` - trader_id: {:?}\",\n                    self.actor_id, self.trader_id\n                )\n            })\n            .borrow()\n    }\n\n    fn cache_api(&self) -> CacheApi<'_> {\n        let cache = self.cache.as_ref().unwrap_or_else(|| {\n            panic!(\n                \"DataActor {} must be registered before calling `cache()` - trader_id: {:?}\",\n                self.actor_id, self.trader_id\n            )\n        });\n        CacheApi::new(cache.as_ref())\n    }\n\n    /// Register the data actor with a trader.","sourceCodeStart":4080,"sourceCodeEnd":4116,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/actor/data_actor.rs#L4080-L4116","documentation":"`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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nlet actor = MyActor::new();\nlet now = actor.clock_ref().timestamp_ns(); // panic\n// after\ntrader.add_actor(MyActor::new());\n// access clock inside on_start via self.clock_ref()","handlingStrategy":"type-guard","validationCode":"assert!(actor.is_registered(), \"clock_ref() requires trader registration\");","typeGuard":"fn clock_available(actor: &DataActor) -> bool { actor.is_registered() }","tryCatchPattern":null,"preventionTips":["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"],"tags":["actor","lifecycle","clock","rust"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}