{"record":{"id":"4d0186593e1b2654","repo":"nautechsystems/nautilus_trader","slug":"venue-venue-is-already-registered","errorCode":null,"errorMessage":"Venue {venue} is already registered","messagePattern":"Venue (.+?) is already registered","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/engine.rs","lineNumber":279,"sourceCode":"        self.backtest_end\n    }\n\n    /// Returns the list of registered venue identifiers.\n    #[must_use]\n    pub fn list_venues(&self) -> Vec<Venue> {\n        self.venues.keys().copied().collect()\n    }\n\n    /// # Errors\n    ///\n    /// Returns an error if the venue is already registered, initializing the simulated exchange\n    /// fails, or registering its execution client fails.\n    pub fn add_venue(&mut self, config: SimulatedVenueConfig) -> anyhow::Result<()> {\n        // `routing` and `frozen_account` flow to the exec client, so capture\n        // them before the config is consumed by the exchange constructor.\n        let venue = config.venue;\n        if self.venues.contains_key(&venue) {\n            anyhow::bail!(\"Venue {venue} is already registered\");\n        }\n\n        let routing = Some(config.routing);\n        let frozen_account = Some(config.frozen_account);\n        let use_message_queue = config.use_message_queue;\n\n        let exchange =\n            SimulatedExchange::new(config, self.kernel.cache.clone(), self.kernel.clock.clone())?;\n        let exchange = Rc::new(RefCell::new(exchange));\n\n        let account_id = AccountId::from(format!(\"{venue}-001\").as_str());\n\n        let exec_client = BacktestExecutionClient::new(\n            self.config.trader_id(),\n            account_id,\n            &exchange,\n            self.kernel.cache.clone(),\n            self.kernel.clock.clone(),","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/engine.rs#L261-L297","documentation":"Each venue in a backtest must be unique: add_venue registers a SimulatedVenue under its Venue key in the engine's venue map. Registering the same venue twice is ambiguous (which exchange would clients route to?), so the engine rejects it eagerly.","triggerScenarios":"Calling BacktestEngine::add_venue twice with SimulatedVenueConfig values whose `venue` fields are equal (e.g. two configs for BINARYBLOCK or \"BINANCE\"), or re-running setup code that registers venues without clearing the engine.","commonSituations":"Copy-pasted venue setup blocks; a loop over venue configs containing duplicates; re-invoking an add_venue setup function on an already-configured engine; accidentally using the same venue name for spot and futures.","solutions":["Use a distinct Venue name for each registration (e.g. BINANCE vs BINANCE_FUTURES)","Deduplicate venue configs before the registration loop","Create a fresh BacktestEngine instead of reusing an already-configured one","Guard registration with a contains/exists check on your own setup state"],"exampleFix":"// before\nengine.add_venue(venue_binance.clone())?;\nengine.add_venue(venue_binance.clone())?;  // duplicate\n// after\nif !registered.contains(&venue_binance.venue) {\n    engine.add_venue(venue_binance.clone())?;\n    registered.insert(venue_binance.venue);\n}","handlingStrategy":"validation","validationCode":"let mut seen = std::collections::HashSet::new();\nfor cfg in &venue_configs {\n    if !seen.insert(cfg.venue) {\n        return Err(format!(\"Duplicate venue in config: {}\", cfg.venue));\n    }\n}","typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(|| engine.add_venue(cfg)) { ... } // prefer:\nif let Err(e) = engine.add_venue(cfg) {\n    if e.to_string().contains(\"already registered\") {\n        log::warn!(\"Venue {} registered twice; skipping\", cfg.venue);\n        return Ok(());\n    }\n    return Err(e);\n}","preventionTips":["Deduplicate venue configs before setup","Never re-run venue registration on an already-configured engine","Use distinct venue names for spot vs futures"],"tags":["backtest","duplicate-registration","venues"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}