nautechsystems/nautilus_trader · error
DataActor must be registered before accessing cache
Error message
DataActor must be registered before accessing cache
What it means
DataActor::cache_ref borrows the shared Cache for reading, but the cache handle is only populated when the actor is registered with a Trader/Node. Calling it before registration panics with this message, enforcing the actor lifecycle: no cache access before registration.
Source
Thrown at crates/common/src/actor/data_actor.rs:219
/// Panics if the actor has not yet been registered.
fn clock_rc(&self) -> Rc<RefCell<dyn Clock>> {
self.core()
.clock
.as_ref()
.expect("DataActor must be registered before accessing clock")
.clone()
}
/// Returns a read-only cache borrow.
///
/// # Panics
///
/// Panics if the actor has not yet been registered.
fn cache_ref(&self) -> Ref<'_, Cache> {
self.core()
.cache
.as_ref()
.expect("DataActor must be registered before accessing cache")
.borrow()
}
/// Returns a clone of the reference-counted cache.
///
/// # Panics
///
/// Panics if the actor has not yet been registered.
fn cache_rc(&self) -> Rc<RefCell<Cache>> {
self.core()
.cache
.as_ref()
.expect("DataActor must be registered before accessing cache")
.clone()
}
}
/// Defines lifecycle callbacks, data handlers, and subscription/requestView on GitHub (pinned to 18893faf8b)
Solutions
- Access the cache only from lifecycle callbacks (on_start and later) that run after registration
- Register the actor before invoking any cache-dependent method
- In tests, register the actor with a test harness/kernel (or populate the core's cache) before exercising handlers
Example fix
// before let prices = actor.cache_ref().prices(...); // panics if called pre-registration // after // inside on_start / on_data, post-registration: let prices = self.cache_ref().prices(...);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure registration completed before any cache access:
// e.g. call sites only in on_start/on_data, never in new().
fn ensure_registered(registered: bool) {
assert!(registered, "cache access requires registration");
} Try / catch
// Panics are not catchable; enforce ordering by only reading cache in lifecycle callbacks:
fn on_start(&mut self) {
let cache = self.cache_ref(); // safe here
} Prevention
- Read the cache only from on_start or later callbacks
- Move any pre-registration cache reads into on_start
- In unit tests, register the actor (or inject cache) before invoking data handlers
When it happens
Trigger: Calling cache_ref() (directly or via helpers like cache_read) from the actor's constructor, before trader.add_actor/node registration, or in tests that build a bare DataActor without registering it.
Common situations: Attempting to read market data/prices in actor initialization code; unit tests instantiating the actor manually and calling data handlers without simulating registration; calling on_start-style logic too early.
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_mut()`
- DataActor {} must be registered before calling `cache()` - t
- DataActor must be registered before accessing clock
- DataActor {} must be registered before calling `clock()` - t
- DataActor {} must be registered before calling `clock_ref()`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/680c3537c5b3a760.
Report an issue: GitHub.