nautechsystems/nautilus_trader · error · anyhow::Error

Timed out requesting open orders for perm_id lookup

Error message

Timed out requesting open orders for perm_id lookup

What it means

The perm_id lookup wraps client.all_open_orders() in tokio::time::timeout(request_timeout_secs). If the request does not complete in time, this error bails. It means TWS/Gateway accepted the connection but never responded to the open-orders request within the configured window.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/core.rs:2223

    }

    async fn resolve_ib_order_id(
        client: &Arc<Client>,
        order_selector: IbOrderSelector,
        account_id: AccountId,
        request_timeout_secs: u64,
    ) -> anyhow::Result<i32> {
        let target_perm_id = match order_selector {
            IbOrderSelector::OrderId(order_id) => return Ok(order_id),
            IbOrderSelector::PermId(perm_id) => perm_id,
        };

        let timeout_dur = Duration::from_secs(request_timeout_secs);
        let raw_account_id = raw_ib_account_code(&account_id);
        let subscription = match tokio::time::timeout(timeout_dur, client.all_open_orders()).await {
            Ok(Ok(subscription)) => subscription,
            Ok(Err(e)) => anyhow::bail!("Failed to request open orders for perm_id lookup: {e}"),
            Err(_) => anyhow::bail!("Timed out requesting open orders for perm_id lookup"),
        };
        let mut subscription = subscription.filter_data();

        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;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Increase request_timeout_secs in the adapter configuration
  2. Check TWS/Gateway responsiveness and restart it if frozen
  3. Retry the perm_id lookup after connectivity is restored
  4. Investigate network latency between the client and Gateway

Example fix

// before
let request_timeout_secs = 5;
// after
let request_timeout_secs = 30;
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight ping with a small timeout before the lookup
tokio::time::timeout(Duration::from_secs(2), client.check_health()).await
    .map_err(|_| anyhow!("gateway unresponsive"))?;

Try / catch

match resolve_perm_id(...).await {
    Err(e) if e.to_string().contains("Timed out requesting open orders") => {
        warn!("gateway slow; retrying with larger timeout");
        with_longer_timeout(|| retry_lookup()).await?
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling the perm_id lookup while Gateway is unresponsive (busy, frozen, restarting), on very slow networks, or when request_timeout_secs is configured too small.

Common situations: IB Gateway hung or performing maintenance; large numbers of open orders slowing the response; low request_timeout_secs in adapter config; network latency/VPN issues.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/65e450973d1f250a. Report an issue: GitHub.