nautechsystems/nautilus_trader · error

order list {} was not fully canceled: status={:?}, order_sta

Error message

order list {} was not fully canceled: status={:?}, order_status={:?}

What it means

The cancel order-list response indicates the list was not fully canceled: listStatusType or listOrderStatus is not AllDone. prepare_cancel_order_list requires the exchange to confirm the whole list reached DONE before emitting cancels, otherwise some orders may remain live while local state says canceled.

Source

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

                )?;
            }
        }
    }

    Ok(prepared)
}

fn prepare_cancel_order_list(
    response: BinanceCancelOrderListResponse,
    order_ids: &mut AHashSet<(InstrumentId, i64)>,
    client_order_ids: &mut AHashSet<ClientOrderId>,
    prepared: &mut Vec<PreparedCancelOrder>,
) -> anyhow::Result<()> {
    anyhow::ensure!(
        response.order_list_id >= 0 && !response.symbol.is_empty(),
        "order list has an invalid list ID or empty symbol",
    );
    anyhow::ensure!(
        response.list_status_type == SbeListStatusType::AllDone
            && response.list_order_status == SbeListOrderStatus::AllDone,
        "order list {} was not fully canceled: status={:?}, order_status={:?}",
        response.order_list_id,
        response.list_status_type,
        response.list_order_status,
    );
    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!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the reported status/list_order_status to see which stage failed
  2. Query open orders for the symbol to find remaining live orders and cancel them individually
  3. Retry the cancel for orders that remain open
  4. Handle partial fills: reconcile fills via the trade stream instead of assuming cancellation

Example fix

// before
// assume cancel-all succeeded
// after
// check status before proceeding, re-query open orders and cancel leftovers individually
Defensive patterns

Strategy: retry

Try / catch

match cancel_all_orders(instrument_id).await {
    Err(e) if e.to_string().contains("not fully canceled") => {
        // re-query open orders and cancel leftovers individually
        let open = query_open_orders(instrument_id).await?;
        for o in open { cancel_order(o.client_order_id).await?; }
    },
    Err(e) => return Err(e),
    Ok(_) => {},
}

Prevention

When it happens

Trigger: cancel_all_orders triggers a cancel order list where the exchange responds with status e.g. DONE vs ALL_DONE variants such as EXEC_STARTED or REJECT, or list_order_status != AllDone because an order in the list already filled or could not be canceled.

Common situations: OCO lists partially filled before the cancel arrived; cancel raced with execution; exchange rejected part of the list cancel due to price/quantity constraints.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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