nautechsystems/nautilus_trader · error
Pool venue chain {blockchain} does not match the client chai
Error message
Pool venue chain {blockchain} does not match the client chain {chain_name} What it means
resolve_pool() parses the instrument ID's venue as a `(blockchain, dex_type)` pair and refuses any instrument whose venue chain differs from the chain this execution client is connected to. Each client instance is bound to exactly one blockchain (`self.chain.name`), so pools on other chains must be routed through that chain's own client. The check runs before any DEX or cache lookup.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:807
Ok(included.tx_hash)
}
fn uniswap_v3_factory(&self) -> anyhow::Result<Address> {
crate::exchanges::get_dex_extended(self.chain.name, &DexType::UniswapV3)
.map(|dex| dex.factory)
.ok_or_else(|| {
anyhow::anyhow!(
"No registered Uniswap V3 deployment for chain {}",
self.chain.name
)
})
}
fn resolve_pool(&self, instrument_id: &InstrumentId) -> anyhow::Result<Pool> {
let (blockchain, dex_type) = instrument_id.venue.parse_dex()?;
if blockchain != self.chain.name {
anyhow::bail!(
"Pool venue chain {blockchain} does not match the client chain {}",
self.chain.name
);
}
if dex_type != DexType::UniswapV3 {
anyhow::bail!("Unsupported DEX type {dex_type}; only UniswapV3 is supported");
}
let pool_identifier = PoolIdentifier::new_checked(instrument_id.symbol.as_str())?;
if !pool_identifier.is_address() {
anyhow::bail!(
"Pool identifier {pool_identifier} is a pool ID; only address identifiers are supported"
);
}
let pool = self
.coreView on GitHub (pinned to 18893faf8b)
Solutions
- Send the instrument to the execution client constructed for its venue chain (make the client lookup keyed by chain).
- Check the instrument ID venue string for typos and correct chain naming (e.g. `ethereum/uniswap_v3:0x...`) so the parsed blockchain matches the client's chain.
- If instruments are configured from an external file, validate at startup that every instrument's venue chain matches the client chain it will be assigned to.
Example fix
// before: single client used for all chains
client.prepare_swap(instrument_id, ...).await?; // instrument on arbitrum
// after: dispatch by chain
let client = clients.get(instrument_id.venue.parse_dex()?.0)
.with_context(|| format!("no client for {}", instrument_id.venue))?;
client.prepare_swap(instrument_id, ...).await?; Defensive patterns
Strategy: validation
Validate before calling
let (blockchain, _dex) = instrument_id.venue.parse_dex()?;
if blockchain != client.chain.name {
anyhow::bail!("instrument {} is on {blockchain}, client is on {}", instrument_id, client.chain.name);
}
// safe to call client.prepare_swap(...).await? Type guard
fn belongs_to_chain(instrument_id: &InstrumentId, chain: &str) -> anyhow::Result<bool> {
Ok(instrument_id.venue.parse_dex()?.0 == chain)
} Try / catch
match client.prepare_swap(&instrument_id, plan).await {
Err(e) if e.to_string().contains("does not match the client chain") => {
error!("wrong client for instrument; re-route to the {} client", instrument_id.venue);
}
other => other?,
} Prevention
- Maintain a map from chain name to its execution client and dispatch instruments by their parsed venue chain.
- Validate all configured instruments against their assigned client chain at startup.
- Standardize venue naming for chains across configs to avoid parse drift.
When it happens
Trigger: Calling `preflight`, `restore_swap_plan`, or `prepare_swap` with an `InstrumentId` whose venue encodes a different blockchain than the client's chain — e.g. passing venue `arbitrum/uniswap_v3` to an Ethereum client, or using a venue string whose chain component is misspelled or renamed so it parses to a different/unknown chain name.
Common situations: Routing instruments to the wrong execution client in a multi-chain setup; venue naming drift (config uses `arb` while the registry expects `arbitrum`); building instrument IDs programmatically with a chain variable that points at the wrong network; running against a testnet client while instruments reference mainnet venues.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Chain ID mismatch at connect: expected {expected_chain_id},
- Unsupported blockchain {blockchain} for RPC connection
- Unsupported DEX type {dex_type}; only UniswapV3 is supported
- Pool identifier {pool_identifier} is a pool ID; only address
- Pool {instrument_id} tokens share a token priority; base and
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d70cbc56c73a1b50.
Report an issue: GitHub.