nautechsystems/nautilus_trader · error

Venue {venue} already routed to {existing_client_id}, cannot

Error message

Venue {venue} already routed to {existing_client_id}, cannot re-route to {client_id}

What it means

Each venue can be routed to only one client. register_venue_routing bails when the venue already maps to a different client ID; re-routing to a new client is not permitted, while routing the same venue to the same client is a no-op (allowed).

Source

Thrown at crates/execution/src/engine/mod.rs:556

    /// Sets routing for a specific venue to a given client ID.
    ///
    /// # Errors
    ///
    /// Returns an error if the client ID is not registered.
    pub fn register_venue_routing(
        &mut self,
        client_id: ClientId,
        venue: Venue,
    ) -> anyhow::Result<()> {
        if !self.clients.contains_key(&client_id) {
            anyhow::bail!("No client registered with ID {client_id}");
        }

        if let Some(existing_client_id) = self.routing_map.get(&venue)
            && *existing_client_id != client_id
        {
            anyhow::bail!(
                "Venue {venue} already routed to {existing_client_id}, \
                 cannot re-route to {client_id}"
            );
        }

        self.routing_map.insert(venue, client_id);
        log::info!("Set client {client_id} routing for {venue}");
        Ok(())
    }

    /// Registers the OMS (Order Management System) type for a strategy.
    ///
    /// If an OMS type is already registered for this strategy, it will be overridden.
    pub fn register_oms_type(&mut self, strategy_id: StrategyId, oms_type: OmsType) {
        self.oms_overrides.insert(strategy_id, oms_type);
        log::info!("Registered OMS::{oms_type:?} for {strategy_id}");
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. If re-routing is intended, deregister the currently routed client (deregister_client removes its routing entries) and then register the new route.
  2. Choose a distinct venue per client so each venue maps to one route.
  3. Skip the call when the existing route already equals the target client (it is a legal no-op).
  4. Validate routing configuration at startup for duplicate venue entries before applying them.

Example fix

// before
engine.register_venue_routing(client_b_id.clone(), venue)?; // venue routed to client_a
// after
if engine.routing_target(&venue) != Some(&client_b_id) {
    engine.deregister_client(current_routed_id)?;
}
engine.register_venue_routing(client_b_id.clone(), venue)?;
Defensive patterns

Strategy: validation

Validate before calling

// skip when the route already points at the target client
if engine.routing_target(&venue).as_ref() != Some(&client_id) {
    engine.register_venue_routing(client_id, venue)?;
}

Try / catch

match engine.register_venue_routing(client_id.clone(), venue.clone()) {
    Err(e) if e.to_string().contains("cannot re-route") => log::warn!("venue {venue} stays on its existing client"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling ExecutionEngine::register_venue_routing for a venue that is already present in routing_map with a different client_id than the one passed in.

Common situations: Assigning a venue to a second client after register_client already claimed it (e.g. switching accounts at runtime); config lists two routes for the same venue; a test registers both a primary and hedge client for one venue.

Related errors


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