nautechsystems/nautilus_trader · error · anyhow::Error

Parent order ID {parent_order_id} not found for order {}

Error message

Parent order ID {parent_order_id} not found for order {}

What it means

When submitting a batch, child orders may reference a parent_order_id. The parent must either be another order in the same batch (present in ib_order_ids) or a previously submitted order known to the adapter's order_id_map. If the parent ID is in neither, this ensure! fires — the parent relationship cannot be resolved for the IB batch submission.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/core_orders.rs:441

        let _submit_guard = order_submit_lock.lock().await;
        let ib_account = account_id
            .to_string()
            .split_once('-')
            .map_or_else(|| account_id.to_string(), |(_, value)| value.to_string());
        let mut ib_order_ids = AHashMap::with_capacity(num_orders);

        for order in orders {
            let ib_order_id = Self::reserve_next_local_order_id(next_order_id)?;
            ib_order_ids.insert(order.client_order_id(), ib_order_id);
        }

        for order in orders {
            if let Some(parent_order_id) = order.parent_order_id()
                && !ib_order_ids.contains_key(&parent_order_id)
            {
                let map = order_id_map.lock();
                anyhow::ensure!(
                    map.contains_key(&parent_order_id),
                    "Parent order ID {parent_order_id} not found for order {}",
                    order.client_order_id(),
                );
            }
        }

        for (index, order) in orders.iter().enumerate() {
            let is_last = index == num_orders - 1;
            let ib_order_id = ib_order_ids[&order.client_order_id()];

            let order_contract =
                Self::resolve_contract_for_instrument(order.instrument_id(), instrument_provider)?;
            let order_contract =
                Self::contract_with_order_exchange_param(order_contract, cmd.params.as_ref())?;

            let order_ref = order.client_order_id().to_string();
            let mut ib_order = nautilus_order_to_ib_order(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the parent order is submitted (and accepted) before submitting the child, or include the parent in the same batch.
  2. Verify the child's parent_order_id matches the parent's actual ClientOrderId exactly.
  3. If the parent was submitted in a prior session, resubmit it or clear the child's parent reference.
  4. Check that order_id_map is persistent/populated as expected after restarts.

Example fix

// before
let child = build_bracket_leg(parent_id: some_stale_id, ...);
// after
let child = build_bracket_leg(parent_id: parent_client_order_id, ...); // must match a live/submitted order
Defensive patterns

Strategy: validation

Validate before calling

if let Some(parent_id) = order.parent_order_id() {
    anyhow::ensure!(submitted_ids.contains(&parent_id), "parent {} not yet submitted", parent_id);
}

Prevention

When it happens

Trigger: Submitting an order whose parent_order_id() was never submitted (or was submitted with a different client_order_id than the one stored in order_id_map), within handle_submit_order_list_async.

Common situations: Bracket/OCO setups where the parent leg failed or was rejected earlier; using stale or regenerated ClientOrderIds after a node restart that cleared order_id_map; typo'd or swapped parent/child IDs.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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