nautechsystems/nautilus_trader · error · anyhow::Error

Venue '{venue_str}' is not a DEX venue (expected format 'Cha

Error message

Venue '{venue_str}' is not a DEX venue (expected format 'Chain:DexId')

What it means

Venue::parse_dex parses a venue identifier like "Ethereum:UniswapV3" into a (Blockchain, DexType) pair and bails when the string has no ':' separator, i.e. it is not in the 'Chain:DexId' DEX venue format. This only validates the format; unknown chain or DEX names raise separate errors afterwards.

Source

Thrown at crates/model/src/identifiers/venue.rs:152

    #[cfg(feature = "defi")]
    #[must_use]
    pub fn is_dex(&self) -> bool {
        self.0.contains(':')
    }

    #[cfg(feature = "defi")]
    /// Parses a venue string to extract blockchain and DEX type information.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - The venue string is not in the format "chain:dex"
    /// - The chain name is not recognized
    /// - The DEX name is not recognized
    pub fn parse_dex(&self) -> anyhow::Result<(Blockchain, DexType)> {
        let venue_str = self.as_str();
        let Some((chain_name, dex_id)) = venue_str.split_once(':') else {
            anyhow::bail!("Venue '{venue_str}' is not a DEX venue (expected format 'Chain:DexId')")
        };

        let chain = Chain::from_chain_name(chain_name).ok_or_else(|| {
            anyhow::anyhow!("Invalid chain '{chain_name}' in venue '{venue_str}'")
        })?;
        let dex_type = DexType::from_dex_name(dex_id)
            .ok_or_else(|| anyhow::anyhow!("Invalid DEX '{dex_id}' in venue '{venue_str}'"))?;

        Ok((chain.name, dex_type))
    }
}

impl Debug for Venue {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "\"{}\"", self.0)
    }
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Format the venue string as 'Chain:DexId', e.g. "Ethereum:UniswapV3".
  2. Check the venue's origin — CEX venues legitimately have no DEX form; gate parse_dex calls on the venue actually being a DEX venue.
  3. Validate the string with split_once(':') before constructing the Venue or calling parse_dex.

Example fix

// before
let venue = Venue::from("UniswapV3");
let (chain, dex) = venue.parse_dex()?;
// after
let venue = Venue::from("Ethereum:UniswapV3");
let (chain, dex) = venue.parse_dex()?;
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_dex_venue(s: &str) -> bool { s.split_once(':').is_some() }

Type guard

fn parse_dex_venue(s: &str) -> Option<Venue> {
    s.split_once(':')?;
    Some(Venue::from(s))
}

Try / catch

match venue.parse_dex() {
    Ok((chain, dex)) => { /* ... */ }
    Err(e) => { /* venue is not Chain:DexId — skip or log */ }
}

Prevention

When it happens

Trigger: Calling venue.parse_dex() on a venue constructed from a plain string such as "BINANCE" or "Uniswap" that lacks the Chain:DexId form.

Common situations: Config files specifying CEX-style venue names for DEX strategies, hardcoded venue strings missing the colon, or venue parsed from user input without format checks.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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