nautechsystems/nautilus_trader · error

Strategy state callback not found

Error message

Strategy {strategy_id} state callback not found

What it means

Raised in `Trader::strategy_state_callbacks` when a strategy ID listed for state recovery has no registered save/load callbacks in the trader's `strategy_state_callbacks` map. The trader cannot persist or restore that strategy's state, so it errors rather than silently skipping it.

Solutions

  1. Ensure strategies are added through the standard path so their state callbacks are registered
  2. Avoid removing/retiring a strategy while state save/load is in progress; serialize lifecycle operations
  3. Keep recovery metadata in sync with `strategy_state_callbacks` after `remove_strategy`/`retire_strategy`
  4. Check the reported `strategy_id` against your configured strategies and drop it from recovery if intentionally removed
Defensive patterns

Strategy: validation

Validate before calling

// before state save/load, confirm each strategy has callbacks
for id in recovery_strategy_ids {
    assert!(trader.has_strategy_state_callbacks(&id), "missing callbacks for {id}");
}

Type guard

fn has_strategy_callbacks(trader: &Trader, strategy_id: &StrategyId) -> bool {
    trader.strategy_state_callbacks().contains_key(strategy_id)
}

Prevention

When it happens

Trigger: Calling trader start/state save while a strategy_id referenced by recovery has no callback entry — typically the strategy was registered without state callbacks, or was removed (e.g. via `retire_strategy`, which clears `strategy_state_callbacks`) while still referenced by the recovery path.

Common situations: Removing a strategy concurrently with a state-save pass; custom strategy registration bypassing the standard callback registration; stale recovery metadata referencing a retired strategy.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a8732939a2b90c09. Report an issue: GitHub.

Appendix: source

Thrown at crates/system/src/trader.rs:1689

                    .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")
                    })
            })
            .collect()
    }

    fn load_component_state<T>(
        component_id: Ustr,
        state: PersistedComponentState,
    ) -> anyhow::Result<()>
    where
        T: DataActor + DataActorNative + Debug + 'static,
    {
        let mut component = try_get_actor_unchecked::<T>(&component_id).ok_or_else(|| {
            anyhow::anyhow!("Component {component_id} not found in actor registry")
        })?;
        component.on_load(state)
    }

View on GitHub (pinned to 18893faf8b)