nautechsystems/nautilus_trader · error

Pool {pool_identifier} is not registered

Error message

Pool {pool_identifier} is not registered

What it means

get_pool is a public accessor that returns the SharedPool registered in the cache for the given PoolIdentifier, and bails when no pool with that identifier exists. Callers must ensure the pool was discovered/registered (e.g. via a PoolCreated event or explicit registration) before querying it.

Source

Thrown at crates/adapters/blockchain/src/data/core.rs:2414

        if !self.cache.get_registered_dexes().contains(dex_id) {
            anyhow::bail!("DEX {dex_id} is not registered in the data client");
        }

        match get_dex_extended(self.chain.name, dex_id) {
            Some(dex) => Ok(dex),
            None => anyhow::bail!("Dex {dex_id} doesn't exist for chain {}", self.chain.name),
        }
    }

    /// Retrieves a pool from the cache by its address.
    ///
    /// # Errors
    ///
    /// Returns an error if the pool is not registered in the cache.
    pub fn get_pool(&self, pool_identifier: &PoolIdentifier) -> anyhow::Result<&SharedPool> {
        match self.cache.get_pool(pool_identifier) {
            Some(pool) => Ok(pool),
            None => anyhow::bail!("Pool {pool_identifier} is not registered"),
        }
    }

    /// Sends a data event to all subscribers through the data channel.
    pub fn send_data(&self, data: DataEvent) {
        if let Some(data_tx) = &self.data_tx {
            log::debug!("Sending {data}");

            if let Err(e) = data_tx.send(data) {
                log::error!("Failed to send data: {e}");
            }
        } else {
            log::error!("No data event channel for sending data");
        }
    }

    /// Disconnects all active connections and cleanup resources.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the pool is registered first (discovery sync / register call) before syncing its events
  2. Set the discovery start block to cover all pools you will query
  3. Normalize pool addresses (checksum/case) before constructing the PoolIdentifier
  4. Check cache.get_pool with the same identifier interactively to confirm what is registered

Example fix

// before
let pool = data_client.get_pool(&pool_identifier)?;
// after
let pool = match data_client.get_pool(&pool_identifier) {
    Ok(pool) => pool,
    Err(_) => {
        data_client.register_pool(&pool_identifier).await?;
        data_client.get_pool(&pool_identifier)?
    }
};
Defensive patterns

Strategy: validation

Validate before calling

if client.get_pool(&pool_identifier).is_err() {
    return Err(anyhow!("pool {pool_identifier} must be registered before use"));
}

Type guard

fn pool_registered(client: &DataClient, id: &PoolIdentifier) -> bool {
    client.get_pool(id).is_ok()
}

Try / catch

match client.get_pool(&pool_identifier) {
    Ok(pool) => pool,
    Err(_) => { client.register_pool(&pool_identifier).await?; client.get_pool(&pool_identifier)? }
}

Prevention

When it happens

Trigger: Calling get_pool (typically from sync_pool_events) with a PoolIdentifier whose pool was never registered in the cache — e.g. a swap/mint log arrives for a pool created before the client's discovery start block, or the identifier address has a checksum/format mismatch.

Common situations: Syncing events from before the DEX/pool registration start block; a pool address from config that was never discovered; address casing or checksum differences between the identifier and registration; the pool was evicted or the cache was reset.

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/4c5fc6e594b5d332. Report an issue: GitHub.