nautechsystems/nautilus_trader · error

load_actor not implemented for PostgreSQL cache adapter: {ac

Error message

load_actor not implemented for PostgreSQL cache adapter: {actor_id}

What it means

The PostgreSQL cache adapter does not implement load_actor; calling it always fails. Actor state blobs are not persisted to/read from the SQL backend, so loading an actor's cached state through this adapter is unsupported.

Source

Thrown at crates/infrastructure/src/sql/cache.rs:875

        Ok(rx.recv()?)
    }

    async fn load_position(&self, position_id: &PositionId) -> anyhow::Result<Option<Position>> {
        let pool = self.pool.clone();
        let position_id = position_id.to_owned();
        let (tx, rx) = std::sync::mpsc::channel();

        tokio::spawn(async move {
            let result = DatabaseQueries::load_position(&pool, &position_id).await;
            if let Err(e) = tx.send(result) {
                log::error!("Failed to send position {position_id}: {e:?}");
            }
        });
        rx.recv()?
    }

    fn load_actor(&self, actor_id: &ActorId) -> anyhow::Result<AHashMap<String, Bytes>> {
        anyhow::bail!("load_actor not implemented for PostgreSQL cache adapter: {actor_id}")
    }

    fn delete_actor(&self, _actor_id: &ActorId) -> anyhow::Result<()> {
        todo!()
    }

    fn load_strategy(&self, strategy_id: &StrategyId) -> anyhow::Result<AHashMap<String, Bytes>> {
        anyhow::bail!("load_strategy not implemented for PostgreSQL cache adapter: {strategy_id}")
    }

    fn delete_strategy(&self, _strategy_id: &StrategyId) -> anyhow::Result<()> {
        todo!()
    }

    fn delete_order(&self, client_order_id: &ClientOrderId) -> anyhow::Result<()> {
        anyhow::bail!(
            "delete_order not implemented for PostgreSQL cache adapter: {client_order_id}"
        )

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Persist actor state via the Redis cache adapter, which implements actor load/save
  2. Do not configure actor state persistence when using the PostgreSQL adapter; keep actor state in-memory or file-based
  3. Implement load_actor in sql/cache.rs if SQL-backed actor state is required

Example fix

// before
let state = cache_db.load_actor(&actor_id)?; // bails on Postgres
// after
if cache_db.is_actor_backed() { // e.g. check adapter kind before use
    let state = cache_db.load_actor(&actor_id)?;
}
Defensive patterns

Strategy: fallback

Validate before calling

if is_postgres_cache(&cache_db) { /* do not call load_actor */ }

Type guard

fn is_postgres_cache(db: &dyn CacheDatabase) -> bool { db.as_any().downcast_ref::<PostgresCache>().is_some() }

Try / catch

match cache_db.load_actor(&actor_id) {
    Ok(state) => state,
    Err(e) if e.to_string().contains("not implemented") => AHashMap::new(), // start with default state
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Starting actors with `load_state`/state persistence configured against a PostgreSQL cache database; calling cache.load_actor (or the sync wrapper shown) for any ActorId with the SQL adapter attached.

Common situations: Moving actor state persistence from Redis to Postgres; enabling a cache database in config and expecting actor state to survive restarts; snapshot restore tooling.

Related errors


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