{"record":{"id":"e15001d6ae4d8d5b","repo":"nautechsystems/nautilus_trader","slug":"dataactor-must-be-registered-before-calling-cl","errorCode":null,"errorMessage":"DataActor {} must be registered before calling `clock_mut()` - trader_id: {:?}","messagePattern":"DataActor (.+?) must be registered before calling `clock_mut\\(\\)` - trader_id: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/actor/data_actor.rs","lineNumber":189,"sourceCode":"/// references do not cross those boundaries.\npub trait DataActorNative {\n    /// Returns the actor core.\n    fn core(&self) -> &DataActorCore;\n\n    /// Returns the mutable actor core.\n    fn core_mut(&mut self) -> &mut DataActorCore;\n\n    /// Returns the mutable clock borrow for the actor.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the actor has not been registered with a trader.\n    fn clock_mut(&mut self) -> RefMut<'_, dyn Clock> {\n        let core = self.core_mut();\n        core.clock\n            .as_ref()\n            .unwrap_or_else(|| {\n                panic!(\n                    \"DataActor {} must be registered before calling `clock_mut()` - trader_id: {:?}\",\n                    core.actor_id, core.trader_id\n                )\n            })\n            .borrow_mut()\n    }\n\n    /// Returns a clone of the reference-counted clock.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the actor has not yet been registered.\n    fn clock_rc(&self) -> Rc<RefCell<dyn Clock>> {\n        self.core()\n            .clock\n            .as_ref()\n            .expect(\"DataActor must be registered before accessing clock\")\n            .clone()","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/actor/data_actor.rs#L171-L207","documentation":"`DataActor::clock_mut()` panics when the actor's internal clock handle is `None`, which happens only if the actor has not been registered with a trader (registration injects the clock, cache, and other context). This is a lifecycle misuse: the accessor is being called outside the registered lifetime.","triggerScenarios":"Calling `clock_mut()` in the actor's constructor or `on_start` before registration, or calling it manually on a standalone `DataActor` never passed to a `Trader`/node.","commonSituations":"Using an actor outside a running trader in tests; doing clock-dependent setup in the constructor instead of lifecycle hooks; creating actors and calling accessors before `trader.add_actor(...)`.","solutions":["Register the actor with a trader (or run it through a node/kernel) before calling `clock_mut()`.","Move clock-dependent logic into `on_start`/other post-registration hooks.","In tests, use the registered harness (e.g. `TestComponentStubs`/register helpers) instead of raw actors."],"exampleFix":"// before\nimpl Actor for MyActor {\n    fn new(...) -> Self {\n        let t = self.clock_mut().timestamp_ns(); // panic\n    }\n}\n// after\nimpl Actor for MyActor {\n    fn on_start(&mut self) {\n        let t = self.clock_mut().timestamp_ns(); // clock injected at registration\n    }\n}","handlingStrategy":"type-guard","validationCode":"// guard before access\nfn clock_ready(actor: &DataActor) -> bool { actor.is_registered() }","typeGuard":"fn clock_ready(actor: &DataActor) -> bool {\n    actor.is_registered() // only true after trader registration injects the clock\n}","tryCatchPattern":"// Rust panics are not catchable in safe code; assert the precondition instead\ndebug_assert!(actor.is_registered(), \"call clock_mut() only after trader registration\");","preventionTips":["Never call clock/cache accessors in constructors or before on_start","Run actors through Trader/node registration even in tests","Keep lifecycle-dependent logic inside lifecycle hook methods"],"tags":["actor","lifecycle","rust","panic"],"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-14T05:17:10.506Z"}