nautechsystems/nautilus_trader · error · anyhow::Error

Unknown dex_name: {dex_name}

Error message

Unknown dex_name: {dex_name}

What it means

The row's `dex_name` string is present but is not recognized by `DexType::from_dex_name`, so no `DexType` can be constructed. The library maintains a fixed mapping of known DEX names; unknown values (new DEXes, renamed DEXes, casing differences) are rejected.

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:2539

                .load_pool_ticks_for_snapshot(
                    chain_id,
                    pool_identifier,
                    block,
                    transaction_index,
                    log_index,
                )
                .await?;

            let dex_name = row
                .try_get::<Option<String>, _>("dex_name")?
                .ok_or_else(|| {
                    anyhow::anyhow!("Missing dex_name for pool snapshot {}", pool_identifier)
                })?;
            let chain = Chain::from_chain_id(chain_id)
                .ok_or_else(|| anyhow::anyhow!("Unknown chain_id: {chain_id}"))?;

            let dex_type = DexType::from_dex_name(&dex_name)
                .ok_or_else(|| anyhow::anyhow!("Unknown dex_name: {dex_name}"))?;

            let dex_extended = crate::exchanges::get_dex_extended(chain.name, &dex_type)
                .ok_or_else(|| {
                    anyhow::anyhow!("No DEX extended found for {} on {}", dex_name, chain.name)
                })?;

            let instrument_id =
                Pool::create_instrument_id(chain.name, &dex_extended.dex, pool_identifier.as_ref());

            Ok(Some(PoolSnapshot::new(
                instrument_id,
                state,
                positions,
                ticks,
                analytics,
                block_position,
                timestamp, // ts_event
                timestamp, // ts_init (same block timestamp)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the stored dex_name against the known DexType names and fix the row if it was written incorrectly.
  2. Upgrade the adapter so its DexType mapping includes the new DEX.
  3. Normalize dex_name values (trim/lowercase) in the writer before persisting.
  4. Delete stale snapshots for unsupported DEXes if they should not be loaded.

Example fix

// before: informal name stored
INSERT ... VALUES ('uni v3');
// after: canonical enum name
INSERT ... VALUES ('uniswap_v3');
Defensive patterns

Strategy: validation

Validate before calling

fn is_known_dex_name(name: &str) -> bool {
    DexType::from_dex_name(name).is_some()
}
// run before load for the target pool's stored dex_name

Type guard

fn known_dex(name: &str) -> Option<DexType> {
    DexType::from_dex_name(name.trim())
}

Try / catch

match load_snapshot(...).await {
    Err(e) if e.to_string().contains("Unknown dex_name") => {
        tracing::error!("dex_name not in registry; upgrade adapter or fix row");
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: Loading a snapshot whose `dex_name` is misspelled, has unexpected casing/whitespace, or names a DEX added after this build (e.g. `uniswap_v4` read by a binary that only knows v2/v3).

Common situations: Version skew between writer and reader binaries; a new DEX integration added on one branch but not another; manual row inserts with informal names like "uni v3".

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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