nautechsystems/nautilus_trader · error

Dex {dex_id} doesn't exist for chain {}

Error message

Dex {dex_id} doesn't exist for chain {}

What it means

After confirming the DEX is registered, get_dex_extended looks up static extended metadata (DexExtended) for the (chain, dex) pair and bails when no such entry exists. This means the DEX is known to the client but has no definition for the configured chain — an unsupported chain/DEX combination.

Source

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

        Ok(())
    }

    /// Determines the starting block for syncing operations.
    fn determine_from_block(&self) -> u64 {
        self.config
            .from_block
            .unwrap_or_else(|| self.cache.min_dex_creation_block().unwrap_or(0))
    }

    /// Retrieves extended DEX information for a registered DEX.
    fn get_dex_extended(&self, dex_id: &DexType) -> anyhow::Result<&DexExtended> {
        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 {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the DEX is supported on the configured chain and remove it if not
  2. Correct the chain name used to construct the data client
  3. Add/extend the DEX catalog entry for this chain if you are developing the adapter
  4. Use a chain-DEX compatibility list in config validation at startup

Example fix

// before: assuming dex works on any chain
let dex = get_dex_extended("arbitrum", &dex_id).expect("dex exists");
// after: check support first
match get_dex_extended(chain.name, &dex_id) {
    Some(dex) => Ok(dex),
    None => bail!("Dex {dex_id} unsupported on chain {}", chain.name),
}
Defensive patterns

Strategy: validation

Validate before calling

let supported = get_dex_extended(chain_name, dex_id).is_some();
if !supported {
    return Err(anyhow!("dex {dex_id} unsupported on {chain_name}"));
}

Type guard

fn dex_supports_chain(chain: &str, dex_id: &DexType) -> bool {
    get_dex_extended(chain, dex_id).is_some()
}

Try / catch

match client.sync_exchange_pools(&dex_id, ...) {
    Err(e) if e.to_string().contains("doesn't exist for chain") => {
        tracing::warn!("skipping {dex_id}: unsupported on this chain");
        Ok(())
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling get_dex_extended (directly or via sync_pool_events, sync_exchange_pools, register_dex, construct_pool_profiler_from_hypersync_rpc) with a DEX registered for the client but not present in the static DEX catalog for self.chain.name.

Common situations: Configuring a DEX on a chain where it does not exist (e.g. a DEX only deployed on mainnet configured for an L2); adding a new DEX to config before the catalog/adapter ships support for it; wrong chain name in client construction.

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/184ee0bf0ae5a93e. Report an issue: GitHub.