nautechsystems/nautilus_trader · error

failed to resolve positive quantity for current order {} (or

Error message

failed to resolve positive quantity for current order {} (order_type={:?}, persistence_type={:?}, price_size={}, bsp_liability={}, size_matched={}, size_remaining={}, size_cancelled={}, size_lapsed={}, size_voided={})

What it means

While converting a Betfair CurrentOrderSummary (from listCurrentOrders) into an OrderStatusReport, quantity resolution found no positive value: price_size.size, the lifecycle sum (matched+remaining+cancelled+lapsed+voided), and bsp_liability (for liability-based on-close orders) were all zero. The parser refuses to emit a zero-quantity report and errors, including the bet id and every size field for diagnosis.

Source

Thrown at crates/adapters/betfair/src/http/parse.rs:85

        OrderStatus::Voided
    } else {
        resolve_order_status(order.status, size_matched, size_closed)
    };

    // Prefer lifecycle sum when price_size.size is zero. Use bsp_liability for
    // on-close orders that report liability without stake/size.
    let total_size = order.price_size.size;
    let lifecycle_qty = size_matched + size_remaining + size_cancelled + size_lapsed + size_voided;
    let qty = if total_size > Decimal::ZERO {
        total_size
    } else if lifecycle_qty > Decimal::ZERO {
        lifecycle_qty
    } else if uses_liability_based_quantity(order) && order.bsp_liability > Decimal::ZERO {
        order.bsp_liability
    } else {
        Decimal::ZERO
    };
    anyhow::ensure!(
        qty > Decimal::ZERO,
        "failed to resolve positive quantity for current order {} \
         (order_type={:?}, persistence_type={:?}, price_size={}, bsp_liability={}, \
         size_matched={}, size_remaining={}, size_cancelled={}, size_lapsed={}, size_voided={})",
        order.bet_id,
        order.order_type,
        order.persistence_type,
        order.price_size.size,
        order.bsp_liability,
        size_matched,
        size_remaining,
        size_cancelled,
        size_lapsed,
        size_voided,
    );
    let quantity = parse_betfair_quantity(qty)?;
    let filled_qty = parse_betfair_quantity(size_matched)?;

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Capture the bet id from the message and inspect the raw record via listCurrentOrders to see its actual fields.
  2. Narrow the order status query window so anomalous stale orders fall outside the request.
  3. File an adapter issue with the logged field values so handling for that order shape can be added.
Defensive patterns

Strategy: try-catch

Try / catch

for order in &response.current_orders {
    match parse_current_order_report(order, account_id, currency, ts_init) {
        Ok(report) => reports.push(report),
        Err(e) => {
            // log with bet id and continue so one anomalous order does not stall reconciliation
            log::warn!("skipping unparseable current order: {e}");
        }
    }
}

Prevention

When it happens

Trigger: An OCM order-status or fill poll returns a current order whose every size field is zero or absent (absent fields default to Decimal::ZERO) — e.g. a fully voided BSP bet with zero liability, or venue data anomalies for on-close orders.

Common situations: Accounts with historical or cancelled orders reporting all-zero sizes; Betfair API changes omitting size for certain order classes; querying wide time ranges that pull in anomalous stale records.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/4ce4821a8db55d72. Report an issue: GitHub.