nautechsystems/nautilus_trader · error

order list {} contains a duplicate order ID

Error message

order list {} contains a duplicate order ID

What it means

While validating a cancel-open-orders OrderList response, the trader collects child orders into a map keyed by order ID and requires each entry to be unique. This error means the payload contained the same order ID twice within one order list, which the Binance API contract forbids — so the response is malformed or mis-decoded.

Source

Thrown at crates/adapters/binance/src/spot/execution.rs:2564

    anyhow::ensure!(
        !response.orders.is_empty() && response.orders.len() == response.order_reports.len(),
        "order list {} has {} orders and {} reports",
        response.order_list_id,
        response.orders.len(),
        response.order_reports.len(),
    );

    let mut list_orders = AHashMap::with_capacity(response.orders.len());
    for order in response.orders {
        anyhow::ensure!(
            order.symbol == response.symbol,
            "order list {} contains order {} for symbol {}, expected {}",
            response.order_list_id,
            order.order_id,
            order.symbol,
            response.symbol,
        );
        anyhow::ensure!(
            list_orders.insert(order.order_id, order).is_none(),
            "order list {} contains a duplicate order ID",
            response.order_list_id,
        );
    }

    for report in response.order_reports {
        anyhow::ensure!(
            report.order_list_id == Some(response.order_list_id),
            "order {} reports order-list ID {:?}, expected {}",
            report.order_id,
            report.order_list_id,
            response.order_list_id,
        );
        let order = list_orders.remove(&report.order_id).with_context(|| {
            format!(
                "order-list report {} is absent from list {}",
                report.order_id, response.order_list_id

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Update the nautilus_binance adapter to the latest version to fix potential SBE decode duplication
  2. Retry the cancel-all request to check if the duplicate payload recurs
  3. Capture and inspect the raw response; if duplication is real, report it to Binance/adapter maintainers
  4. Rule out middleware or proxies that could duplicate response frames
Defensive patterns

Strategy: validation

Validate before calling

let ids: AHashSet<i64> = response.orders.iter().map(|o| o.order_id).collect();
if ids.len() != response.orders.len() {
    return Err(anyhow!("order list {} contains duplicate order IDs", response.order_list_id));
}

Type guard

fn no_duplicate_order_ids(resp: &BinanceCancelOrderListResponse) -> bool {
    let ids: AHashSet<i64> = resp.orders.iter().map(|o| o.order_id).collect();
    ids.len() == resp.orders.len()
}

Try / catch

match prepare_cancel_all_orders(...) {
    Ok(p) => handle(p),
    Err(e) if e.to_string().contains("duplicate order ID") => log::error!("malformed list payload: {e}"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Binance cancel-open-orders returns an OrderList response whose orders[] array contains two entries with the identical orderId — arising from a decoding bug, duplicate message assembly, or corrupted SBE data.

Common situations: Adapter/SBE schema drift after a Binance protocol update; duplicated frames from a replayed or retried response being merged; corrupted binary payloads through intermediaries.

Related errors


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