nautechsystems/nautilus_trader · error · anyhow::Error
Cannot resolve PERM-{target_perm_id}: matching open order ha
Error message
Cannot resolve PERM-{target_perm_id}: matching open order has no IB order_id What it means
During perm_id lookup, a matching open order was found whose IB order_id is 0 (unassigned). IB uses order_id 0 for orders not originating from this API client (e.g. placed manually in TWS), so the perm_id cannot be mapped back to an API order_id and this error bails.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/core.rs:2245
while let Some(order_result) = subscription.next().await {
let Orders::OrderData(data) = order_result? else {
continue;
};
if !Self::is_active_open_order(&data.order) {
continue;
}
if !data.order.account.is_empty() && data.order.account != raw_account_id {
continue;
}
if data.order.perm_id != target_perm_id {
continue;
}
if data.order_id == 0 {
anyhow::bail!(
"Cannot resolve PERM-{target_perm_id}: matching open order has no IB order_id"
);
}
return Ok(data.order_id);
}
anyhow::bail!("Cannot resolve PERM-{target_perm_id}: no matching open order found")
}
fn is_active_open_order(order: &ibapi::orders::Order) -> bool {
!order.deactivate
}
fn is_definitive_order_submit_error(error: &ibapi::Error) -> bool {
matches!(
error,
ibapi::Error::InvalidArgument(_) | ibapi::Error::ServerVersion(_, _, _)View on GitHub (pinned to 18893faf8b)
Solutions
- Place orders through the same API client that is performing the lookup
- Re-request open orders after IB assigns an order_id, or use reqOpenOrders for the owning client to trigger assignment
- Match orders by perm_id directly instead of requiring an API order_id
- Verify you are resolving the correct perm_id (not one belonging to a manual order)
Defensive patterns
Strategy: fallback
Validate before calling
// after finding data.order.perm_id == target_perm_id, check availability first
if data.order_id == 0 { /* cannot map via API order_id; use perm_id-based handling */ } Type guard
fn has_api_order_id(data: &OrderData) -> Option<i32> {
(data.order_id != 0).then_some(data.order_id)
} Try / catch
match resolve_perm_id(perm_id).await {
Ok(order_id) => order_id,
Err(e) if e.to_string().contains("has no IB order_id") => {
info!("PERM-{perm_id} is a non-API order; matching by perm_id only");
fall_back_to_perm_id_matching(perm_id)
}
Err(e) => return Err(e),
} Prevention
- Place and manage orders through the same API client performing reconciliation
- Use a stable client_id so IB retains order_id assignments
- Treat perm_id as the canonical external identifier, not order_id
- Skip or flag manual orders instead of failing the whole reconciliation
When it happens
Trigger: An order placed outside this API session (manual in TWS, or from a different client) has a perm_id equal to the target, but data.order_id == 0 in the open-orders snapshot.
Common situations: Reconciling orders placed manually or by another automation session; adapter restarted with a new client_id so IB returns unassigned order_ids; resolving a perm_id that belongs to a non-API order.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Failed to request open orders for perm_id lookup: {e}
- Timed out requesting open orders for perm_id lookup
- No order found for client_order_id={cid}
- Order not found in open orders or events: {venue_order_id}
- Finalized execution transaction {tx_hash} no longer has a re
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/68916ccdc43a4aff.
Report an issue: GitHub.