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
- Format the venue string as 'Chain:DexId', e.g. "Ethereum:UniswapV3".
- Check the venue's origin — CEX venues legitimately have no DEX form; gate parse_dex calls on the venue actually being a DEX venue.
- 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
- Always construct DEX venues from the 'Chain:DexId' constant rather than free-form strings.
- Keep CEX and DEX venue handling in separate code paths.
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
- Invalid execution time format: {time_str}
- failed to parse any of {input_len} Lighter instruments: {}
- invalid price `{value}`: {e}
- invalid quantity `{value}`: {e}
- Invalid bar spec: no aggregation suffix in '{value}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/47bcf9fc3efe0186.
Report an issue: GitHub.