nautechsystems/nautilus_trader · error · anyhow::Error

DEX {dex_id:?} has not been registered

Error message

DEX {dex_id:?} has not been registered

What it means

load_pools loads persisted pools for a given DEX, but first requires that the DEX has been registered in the cache's in-memory dex registry (via get_dex). This error is thrown when load_pools is called with a DexType that was never registered, so the cache cannot resolve the DEX to load pools for.

Source

Thrown at crates/adapters/blockchain/src/cache/mod.rs:361

            self.invalid_tokens.extend(invalid_tokens);
        }
        Ok(())
    }

    /// Loads DEX exchange pools from the database into the in-memory cache.
    ///
    /// Returns the loaded pools.
    ///
    /// # Errors
    ///
    /// Returns an error if the DEX has not been registered or if database operations fail.
    pub async fn load_pools(&mut self, dex_id: &DexType) -> anyhow::Result<Vec<Pool>> {
        let mut loaded_pools = Vec::new();

        if let Some(database) = &self.database {
            let dex = self
                .get_dex(dex_id)
                .ok_or_else(|| anyhow::anyhow!("DEX {dex_id:?} has not been registered"))?;
            let pool_rows = database
                .load_pools(self.chain.clone(), &dex_id.to_string())
                .await?;
            log::debug!(
                "Loading {} pools for DEX {} from cache database",
                pool_rows.len(),
                dex_id,
            );

            for pool_row in pool_rows {
                if let Some(pool) = self.build_pool_from_row(&pool_row, &dex) {
                    loaded_pools.push(pool.clone());
                    self.pools.insert(pool.pool_identifier, Arc::new(pool));
                }
            }
        }
        Ok(loaded_pools)
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Register the DEX on the cache (e.g. add_dex) before calling load_pools
  2. Fix startup ordering so DEX registration precedes pool loading
  3. Verify the DexType value matches one actually configured/registered (watch for typos or wrong chain)
  4. If the cache is rebuilt at runtime, re-register all DEXes as part of rebuild

Example fix

// before
let pools = cache.load_pools(&DexType::UniswapV3).await?; // never registered
// after
cache.add_dex(DexType::UniswapV3, dex_contract).await?;
let pools = cache.load_pools(&DexType::UniswapV3).await?;
Defensive patterns

Strategy: validation

Validate before calling

if cache.get_dex(&dex_id).is_none() {
    eprintln!("DEX {dex_id:?} must be registered before load_pools");
}

Type guard

fn dex_registered(cache: &BlockchainCache, dex_id: &DexType) -> bool {
    cache.get_dex(dex_id).is_some()
}

Try / catch

match cache.load_pools(&dex_id).await {
    Err(e) if e.to_string().contains("has not been registered") => {
        // register the DEX then retry once
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling cache.load_pools(&dex_id) where dex_id was never added via the cache's DEX registration method (e.g. add_dex/register_dex), or after the cache was recreated/reset losing registered DEXes.

Common situations: Loading pools on a fresh cache instance without re-registering DEXes first; a typo or wrong variant in DexType; startup ordering where pool loading runs before DEX registration completes.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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