nautechsystems/nautilus_trader · error · anyhow::Error
IB order ID {ib_order_id} is already mapped to client order
Error message
IB order ID {ib_order_id} is already mapped to client order {existing_client_order_id} What it means
cache_cancel_order_tracking updates the venue_order_id_map under a lock so order-status callbacks see a complete identity mapping. If the IB order ID being registered for a cancel already maps to a DIFFERENT client order ID, the adapter refuses to overwrite it via anyhow::ensure! — this indicates an identity collision or duplicate/mismatched cancel for that venue order.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/core_tracking.rs:218
}
#[allow(clippy::too_many_arguments)]
pub(super) fn cache_cancel_order_tracking(
ib_order_id: i32,
cmd: &CancelOrder,
target_order: &OrderAny,
order_id_map: &Arc<Mutex<AHashMap<ClientOrderId, i32>>>,
venue_order_id_map: &Arc<Mutex<AHashMap<i32, ClientOrderId>>>,
instrument_id_map: &Arc<Mutex<AHashMap<i32, InstrumentId>>>,
trader_id_map: &Arc<Mutex<AHashMap<i32, TraderId>>>,
strategy_id_map: &Arc<Mutex<AHashMap<i32, StrategyId>>>,
) -> anyhow::Result<()> {
// Order-status callbacks first map the IB order ID to a client order ID, then read
// its instrument, trader, and strategy IDs. Hold this lock while updating all maps
// so a callback sees either the complete identity or no route at all.
let mut venue_map = venue_order_id_map.lock();
if let Some(existing_client_order_id) = venue_map.get(&ib_order_id) {
anyhow::ensure!(
*existing_client_order_id == cmd.client_order_id,
"IB order ID {ib_order_id} is already mapped to client order {existing_client_order_id}"
);
}
venue_map.remove(&ib_order_id);
order_id_map.lock().insert(cmd.client_order_id, ib_order_id);
instrument_id_map
.lock()
.insert(ib_order_id, target_order.instrument_id());
trader_id_map
.lock()
.insert(ib_order_id, target_order.trader_id());
strategy_id_map
.lock()
.insert(ib_order_id, target_order.strategy_id());
venue_map.insert(ib_order_id, cmd.client_order_id);
View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the client_order_id in the cancel command matches the one originally submitted for that IB order.
- Clear stale venue_order_id_map entries (re-sync order state) after reconnects/restarts.
- Ensure all mapping updates go through the same locked path; audit for code writing venue maps without the lock.
- Log both IDs at the collision to identify which component is issuing the mismatched cancel.
Example fix
// before
cancel_cmd.client_order_id = ClientOrderId::new("O-20260908-002"); // mismatched
// after
cancel_cmd.client_order_id = original_submit_client_order_id; // must equal the mapped ID Defensive patterns
Strategy: validation
Validate before calling
let mapped = venue_order_id_map.lock().get(&ib_order_id).cloned();
if let Some(existing) = mapped {
anyhow::ensure!(existing == cmd.client_order_id, "cancel client_order_id {} != mapped {}", cmd.client_order_id, existing);
} Prevention
- Always cancel using the client_order_id returned from the original submission.
- Re-sync venue/order maps after reconnects before issuing cancels.
- Never reuse client order IDs across orders.
When it happens
Trigger: Calling cache_cancel_order_tracking with a command whose client_order_id does not match the client_order_id already mapped to ib_order_id in venue_order_id_map — e.g. two cancel commands with different client IDs for the same venue order, or a stale/mismatched ID mapping.
Common situations: Duplicate cancel submissions after a reconnect where IDs were remapped; strategy bugs reusing client order IDs; race between an order-status callback and a cancel when the lock discipline is bypassed; node restart with partially restored mappings.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to connect after {max_attempts} attempts
- Unknown IB security type: {value}
- Unknown IB option right: {value}
- Unknown IB historical tick type: {value}
- Unknown IB action: {value}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/332f136181784f13.
Report an issue: GitHub.