nautechsystems/nautilus_trader · error · anyhow::Error
failed to resolve positive quantity for stream order update
Error message
failed to resolve positive quantity for stream order update {} (order_type={:?}, persistence_type={:?}, size={}, bsp_liability={:?}, size_matched={:?}, size_remaining={:?}, size_cancelled={:?}, size_lapsed={:?}, size_voided={:?}) What it means
Stream-path counterpart of the OCM quantity check: while converting a stream OrderChangeMessage into report data, stream_order_quantity found size (s), bsp liability (bsp), and matched/remaining/cancelled/lapsed/voided (sm/sr/sc/sl/sv) all zero or absent, so the parser refuses to build a report. The error carries the update id and every raw size field for diagnosis.
Source
Thrown at crates/adapters/betfair/src/stream/parse.rs:829
let size_matched = uo.sm.unwrap_or(Decimal::ZERO);
let size_cancelled = uo.sc.unwrap_or(Decimal::ZERO);
let size_lapsed = uo.sl.unwrap_or(Decimal::ZERO);
let size_voided = uo.sv.unwrap_or(Decimal::ZERO);
// Include lapsed/voided in the closed quantity for status resolution
let size_closed = size_cancelled + size_lapsed + size_voided;
let order_status = if uo.status == StreamingOrderStatus::ExecutionComplete
&& size_voided > Decimal::ZERO
&& size_cancelled.is_zero()
&& size_lapsed.is_zero()
{
OrderStatus::Voided
} else {
resolve_streaming_order_status(uo.status, size_matched, size_closed)
};
let quantity_decimal = stream_order_quantity(uo);
anyhow::ensure!(
quantity_decimal > Decimal::ZERO,
"failed to resolve positive quantity for stream order update {} \
(order_type={:?}, persistence_type={:?}, size={}, bsp_liability={:?}, \
size_matched={:?}, size_remaining={:?}, size_cancelled={:?}, size_lapsed={:?}, size_voided={:?})",
uo.id,
uo.ot,
uo.pt,
uo.s,
uo.bsp,
uo.sm,
uo.sr,
uo.sc,
uo.sl,
uo.sv,
);
let quantity = parse_betfair_quantity(quantity_decimal)?;
let filled_qty = parse_betfair_quantity(size_matched)?;
View on GitHub (pinned to a4b06ed870)
Solutions
- Correlate the logged uo.id with listCurrentOrders output to see the venue's record for that bet.
- Capture the raw OCM message and file an adapter issue so the shape can be handled.
- If isolated to specific markets/bets, exclude them from the order stream subscription as a workaround.
Defensive patterns
Strategy: try-catch
Try / catch
for uo in &order_changes {
match parse_stream_order_update(uo, account_id, currency, ts_init) {
Ok(report) => reports.push(report),
Err(e) => {
// log the update id and continue so one bad OCM message does not kill the stream handler
log::warn!("skipping unparseable stream order update: {e}");
}
}
} Prevention
- Capture raw OCM frames in debug tooling when anomalous bets are suspected.
- Correlate failing update ids with listCurrentOrders records before reporting.
- Keep the adapter updated so parser coverage for unusual venue payloads improves.
When it happens
Trigger: An order stream (OCM) update whose every quantity field is zero/None — e.g. a voided BSP bet at market closure, or venue data anomalies where size fields are omitted.
Common situations: Accounts subscribed to order streams with BSP bets that got voided; API changes omitting size fields for certain order classes.
Related errors
- failed to resolve positive quantity for current order {} (or
- missing persistence type for order update {}
- BacktestNode state is unavailable when dispose_on_completion
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/fa675b3f34250a15.
Report an issue: GitHub.