{"record":{"id":"b524cc18272a7f19","repo":"nautechsystems/nautilus_trader","slug":"orderlist-denied-orders-must-share-the-same-venue","errorCode":null,"errorMessage":"OrderList denied: orders must share the same venue; expected {first_venue}, found {} on {}","messagePattern":"OrderList denied: orders must share the same venue; expected (.+?), found (.+?) on (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/trading/src/strategy/mod.rs","lineNumber":221,"sourceCode":"    {\n        if orders.is_empty() {\n            log::error!(\"OrderList denied: no orders to submit\");\n            anyhow::bail!(\"OrderList denied: no orders to submit\");\n        }\n\n        for order in &orders {\n            if order.status() != OrderStatus::Initialized {\n                anyhow::bail!(\n                    \"Order in list denied: invalid status for {}, expected INITIALIZED\",\n                    order.client_order_id()\n                );\n            }\n        }\n\n        let first_venue = orders[0].instrument_id().venue;\n        for order in &orders {\n            if order.instrument_id().venue != first_venue {\n                anyhow::bail!(\n                    \"OrderList denied: orders must share the same venue; \\\n                     expected {first_venue}, found {} on {}\",\n                    order.instrument_id().venue,\n                    order.client_order_id(),\n                );\n            }\n        }\n\n        let should_deny = {\n            let core = StrategyNative::strategy_core_mut(self);\n            let tag = core.market_exit_tag;\n            core.is_exiting\n                && orders.iter().any(|o| {\n                    !o.is_reduce_only() && !o.tags().is_some_and(|tags| tags.contains(&tag))\n                })\n        };\n\n        if should_deny {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/trading/src/strategy/mod.rs#L203-L239","documentation":"All orders in one OrderList must target the same venue. submit_order_list takes the venue of the first order and bails if any subsequent order's instrument_id.venue differs, because a list is processed as a single atomic submission to one execution venue.","triggerScenarios":"Passing orders for instruments on two or more venues (e.g. BINANCE and BYBIT, or an equities venue and a futures venue) in a single submit_order_list call.","commonSituations":"Multi-venue strategies batching orders from an aggregation loop; a grouping bug where orders are collected across instruments without partitioning by venue.","solutions":["Partition orders by instrument_id.venue and submit one OrderList per venue.","Group orders by instrument before batching so a list never spans venues.","Assert all orders share the first order's venue before calling submit_order_list."],"exampleFix":"// before\nself.submit_order_list(OrderList(all_orders))\n\n// after\nfrom itertools import groupby\nfor venue, group in groupby(sorted(all_orders, key=lambda o: o.instrument_id.venue), key=lambda o: o.instrument_id.venue):\n    self.submit_order_list(OrderList(list(group)))","handlingStrategy":"validation","validationCode":"venues = {o.instrument_id.venue for o in orders}\nif len(venues) > 1:\n    raise ValueError(f\"order list spans venues: {venues}; submit one list per venue\")","typeGuard":"def single_venue(orders) -> bool:\n    return len({o.instrument_id.venue for o in orders}) <= 1","tryCatchPattern":"try:\n    self.submit_order_list(order_list)\nexcept RuntimeError as e:\n    if \"must share the same venue\" in str(e):\n        self.log.error(\"split batch by venue and resubmit\")\n    else:\n        raise","preventionTips":["Group orders by instrument_id.venue before batching submissions","Never aggregate orders across instruments on different venues into one list","Add an assert/single-venue check in any batch-submission helper"],"tags":["rust","strategy","order-submission","multi-venue"],"backgroundTag":"invalid-argument-value","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"}