nautechsystems/nautilus_trader · error
Actor {actor_id} state callback not found
Error message
Actor {actor_id} state callback not found What it means
Raised in `Trader::actor_state_callbacks` when building the set of state-save/load callbacks for state recovery: an actor ID was listed for recovery but no callbacks are registered for it in the trader's `actor_state_callbacks` map. This indicates an internal inconsistency — an actor is tracked for persistence without its callback pair.
Source
Thrown at crates/system/src/trader.rs:1673
}
}
if errors.is_empty() {
Ok(())
} else {
anyhow::bail!("Failed to save component state: {}", errors.join("; "))
}
}
fn actor_state_callbacks(&self) -> anyhow::Result<Vec<(ActorId, ComponentStateCallbacks)>> {
self.actor_ids
.iter()
.map(|actor_id| {
self.actor_state_callbacks
.get(actor_id)
.copied()
.map(|callbacks| (*actor_id, callbacks))
.ok_or_else(|| anyhow::anyhow!("Actor {actor_id} state callback not found"))
})
.collect()
}
fn strategy_state_callbacks(
&self,
) -> anyhow::Result<Vec<(StrategyId, ComponentStateCallbacks)>> {
self.strategy_ids
.iter()
.map(|strategy_id| {
self.strategy_state_callbacks
.get(strategy_id)
.copied()
.map(|callbacks| (*strategy_id, callbacks))
.ok_or_else(|| {
anyhow::anyhow!("Strategy {strategy_id} state callback not found")
})
})View on GitHub (pinned to 18893faf8b)
Solutions
- Register the actor's save/load state callbacks when adding it (or use the standard Actor registration path) so the map entry exists
- Check whether the actor was added after `load_state` collected its ID and re-order initialization
- If using custom trader plumbing, keep `actor_state_callbacks` in sync with registered actors
- Report/inspect the specific `actor_id`; rebuild the trader config so only actors with state callbacks are included in recovery
Defensive patterns
Strategy: validation
Validate before calling
// ensure every actor listed for recovery has state callbacks registered
for id in recovery_actor_ids {
assert!(trader.has_actor_state_callbacks(&id), "missing callbacks for {id}");
} Type guard
fn has_state_callbacks(trader: &Trader, actor_id: &ActorId) -> bool {
trader.actor_state_callbacks().contains_key(actor_id)
} Prevention
- Register actors only through the standard path that installs save/load callbacks
- Keep recovery metadata derived from the same registration code as the callback map
- Sync callback removal with actor removal in custom lifecycle code
- Fail fast at config time if a recovery-listed actor lacks callbacks
When it happens
Trigger: Calling trader start/state save when an actor_id present in the component registry (or persistence list) has no entry in `self.actor_state_callbacks` — e.g. the actor was added without state callbacks, or was removed while still referenced by the recovery list.
Common situations: Custom actor registration paths that skip `save()`/`load()` callback registration; modifying trader internals; a version mismatch where recovery metadata references actors registered differently in the current version.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Strategy {strategy_id} state callback not found
- DataActor {actor_id} already registered with trader {existin
- Cannot add actor while node is running, add actors before ru
- Python on_order failed: {e}
- Python on_order_list failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a93da8e1f8566daf.
Report an issue: GitHub.