nautechsystems/nautilus_trader · error · anyhow::Error

Unknown pool {instrument_id}; not found in the shared engine

Error message

Unknown pool {instrument_id}; not found in the shared engine cache

What it means

Pool resolution reads the shared engine cache for the Pool object associated with the instrument id. If the cache has no entry for that instrument, the client cannot proceed (it needs token0/token1 and pool state) and raises this error.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:830

        if dex_type != DexType::UniswapV3 {
            anyhow::bail!("Unsupported DEX type {dex_type}; only UniswapV3 is supported");
        }

        let pool_identifier = PoolIdentifier::new_checked(instrument_id.symbol.as_str())?;
        if !pool_identifier.is_address() {
            anyhow::bail!(
                "Pool identifier {pool_identifier} is a pool ID; only address identifiers are supported"
            );
        }

        let pool = self
            .core
            .cache()
            .pool(instrument_id)
            .cloned()
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "Unknown pool {instrument_id}; not found in the shared engine cache"
                )
            })?;

        if pool.token0.get_token_priority() == pool.token1.get_token_priority() {
            anyhow::bail!(
                "Pool {instrument_id} tokens share a token priority; base and quote orientation is ambiguous"
            );
        }

        Ok(pool)
    }

    /// Authenticates every persisted signed transaction in this execution database.
    ///
    /// Run this while the execution client is disconnected. The check takes a stable table lock,
    /// reads in bounded batches, and returns counts, deployment identity, key IDs, and database
    /// roles with direct ownership or `SELECT` grants.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the engine subscribes to / loads the pool into the cache before calling prepare_swap or preflight
  2. Verify the instrument_id matches the pool instrument exactly (venue, symbol, tick size)
  3. Warm the cache at startup (load pool instruments) prior to restoring swap plans

Example fix

// before
client.prepare_swap(instrument_id).await?; // pool never cached
// after
engine.cache().add_pool(pool); // or subscribe to the pool first
client.prepare_swap(instrument_id).await?;
Defensive patterns

Strategy: validation

Validate before calling

if engine.cache().pool(instrument_id).is_none() {
    return Err(format!("pool {} not cached; subscribe/load it first", instrument_id));
}

Try / catch

match client.prepare_swap(instrument_id).await {
    Err(e) if e.to_string().contains("not found in the shared engine cache") => {
        // warm the cache / fix instrument id, then retry once
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling preflight, restore_swap_plan, or prepare_swap with an instrument_id whose pool was never loaded into the engine cache — e.g., no data subscription for the pool, cache cleared, or the instrument id is wrong.

Common situations: Bot started without subscribing to the pool's market data so the pool object was never cached; instrument id constructed with wrong venue/instrument symbol; engine restarted and cache not warmed before swap operations.

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/3686fa8d228c9cc7. Report an issue: GitHub.