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
- Ensure the engine subscribes to / loads the pool into the cache before calling prepare_swap or preflight
- Verify the instrument_id matches the pool instrument exactly (venue, symbol, tick size)
- 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
- Warm the cache with all pool instruments at startup before accepting swap commands
- Subscribe to pool data so the cache stays populated
- Validate instrument_id construction (venue/symbol) against the manifest
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
- Pool {pool_identifier} is not registered
- Lighter fill instrument {instrument_id} missing from cache
- Instrument {instrument_id} not found in cache
- Instrument {symbol} not found in cache
- Instrument {symbol} not in cache
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3686fa8d228c9cc7.
Report an issue: GitHub.