{"record":{"id":"d7a65b8a484214d7","repo":"nautechsystems/nautilus_trader","slug":"no-valid-interactive-brokers-order-id-available","errorCode":null,"errorMessage":"No valid Interactive Brokers order ID available","messagePattern":"No valid Interactive Brokers order ID available","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/execution/core.rs","lineNumber":362,"sourceCode":"            {\n                tracing::error!(\"Error submitting order list: {e}\");\n            }\n        };\n\n        self.pending_tasks\n            .spawn(future)\n            .context(\"failed to register IB execution command task\")?;\n\n        Ok(())\n    }\n\n    fn cached_order_for_modify(&self, client_order_id: &ClientOrderId) -> Option<OrderAny> {\n        self.core.cache().order(client_order_id).map(|o| o.clone())\n    }\n\n    fn reserve_next_local_order_id(next_order_id: &Arc<Mutex<i32>>) -> anyhow::Result<i32> {\n        let mut guard = next_order_id.lock();\n        anyhow::ensure!(\n            *guard > 0,\n            \"No valid Interactive Brokers order ID available\"\n        );\n        let order_id = *guard;\n        *guard += 1;\n        Ok(order_id)\n    }\n\n    fn apply_client_order_id_floor(next_id: i32, client_id: i32) -> i32 {\n        let client_slot = client_id.unsigned_abs() % 1000;\n        if client_slot == 0 {\n            return next_id;\n        }\n\n        let order_id_floor = (client_slot as i32) * 1_000_000;\n        if next_id > order_id_floor {\n            next_id\n        } else {","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/execution/core.rs#L344-L380","documentation":"reserve_next_local_order_id locks the shared next_order_id counter and ensures it is positive before handing out an IB order ID. If the counter is zero or negative — meaning no valid order ID has been received from the IB gateway (via the nextValidId message) — this error is thrown. It guards against issuing order IDs before the connection is properly seeded.","triggerScenarios":"Submitting an order (which reserves a local order ID) before the IB gateway has delivered the next valid order ID, or if a stale/invalid value (<= 0) was stored in the counter.","commonSituations":"Sending orders immediately after client start before the nextValidId handshake completes; reconnect logic resetting the counter to 0; gateway issues that prevent the initial order ID message from arriving.","solutions":["Wait for the client connection/handshake to complete (next valid order ID received) before submitting orders.","Verify the connect() flow populates next_order_id with the value from IB's nextValidId and logs it.","Retry order submission after the client reports it is fully connected; add readiness gating in the trading node before dispatching orders."],"exampleFix":"// before\nlet order_id = self.reserve_next_local_order_id()?;\n// after\nif !self.is_order_id_ready() {\n    anyhow::bail!(\"Cannot submit order: IB order ID not yet received from gateway\");\n}\nlet order_id = self.reserve_next_local_order_id()?;","handlingStrategy":"try-catch","validationCode":"fn order_ids_available(next_order_id: &Arc<Mutex<i32>>) -> bool {\n    *next_order_id.lock() > 0\n}","typeGuard":null,"tryCatchPattern":"match reserve_next_local_order_id(&next_order_id) {\n    Ok(id) => submit(id),\n    Err(e) => { tracing::warn!(\"Order ID not ready: {}\", e); defer_until_connected(); }\n}","preventionTips":["Gate order submission on the client's fully-connected/nextValidId-received state.","Log the initial order ID when received to confirm handshake completion.","On reconnect, re-request the next valid order ID before resuming order flow."],"tags":["order-management","interactive-brokers","state","initialization"],"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"}