nautechsystems/nautilus_trader · error · anyhow::Error
invalid order quantity
Error message
invalid order quantity
What it means
build_ws_order_status_report() validates quantities before conversion to shares: the venue-reported original_size must parse to a decimal > 0, and size_matched (filled amount) must be >= 0 (an empty size_matched is treated as 0 for unfilled FOK cancellations). 'invalid order quantity' means original_size was zero/negative or size_matched was negative — the venue message cannot describe a real order, so the report is rejected.
Source
Thrown at crates/adapters/polymarket/src/websocket/dispatch.rs:1387
let order_status =
crate::execution::parse::resolve_order_status(status.status, order.event_type);
let order_side = OrderSide::from(order.side);
let time_in_force = TimeInForce::from(order_type);
let size_precision = instrument.size_precision();
let price_precision = instrument.price_precision();
let price_dec = parse_decimal_exact(&order.price)?;
anyhow::ensure!(
price_dec > Decimal::ZERO && price_dec < Decimal::ONE,
"order price must be in (0, 1)"
);
let quantity_dec = parse_decimal_exact(&order.original_size)?;
// Unfilled FOK cancellations carry an empty size_matched in captured venue messages
let filled_dec = if order.size_matched.is_empty() {
Decimal::ZERO
} else {
parse_decimal_exact(&order.size_matched)?
};
anyhow::ensure!(
quantity_dec > Decimal::ZERO && filled_dec >= Decimal::ZERO,
"invalid order quantity"
);
let quantity = Quantity::from_decimal_dp(
original_size_to_shares(quantity_dec, price_dec, order.side, order_type)?,
size_precision,
)?;
let filled_qty = Quantity::from_decimal_dp(filled_dec, size_precision)?;
let price = Price::from_decimal_dp(price_dec, price_precision)?;
let mut report = OrderStatusReport::new(
account_id,
instrument.id(),
None,
venue_order_id,
order_side.into(),
OrderType::Limit,
time_in_force,View on GitHub (pinned to 18893faf8b)
Solutions
- Log the raw order payload to confirm what original_size/size_matched actually contained
- Update the adapter's field mapping if the venue schema changed so quantities land in the right fields
- Skip non-reportable message shapes upstream instead of building a report with degenerate quantities
- Fix test fixtures to carry a positive original_size (and non-negative size_matched)
Example fix
// before
anyhow::ensure!(
quantity_dec > Decimal::ZERO && filled_dec >= Decimal::ZERO,
"invalid order quantity"
);
// after — reject degenerate messages upstream before parsing
if order.original_size.is_empty() {
return Ok(None); // no original size: nothing to report
}
anyhow::ensure!(
quantity_dec > Decimal::ZERO && filled_dec >= Decimal::ZERO,
"invalid order quantity"
); Defensive patterns
Strategy: validation
Validate before calling
let qty: f64 = order.original_size.parse()?;
let filled: f64 = if order.size_matched.is_empty() { 0.0 } else { order.size_matched.parse()? };
if !(qty > 0.0 && filled >= 0.0) {
return Ok(None); // degenerate venue message; skip instead of failing the report
} Type guard
fn has_valid_venue_quantities(order: &WsOrder) -> bool {
let qty = order.original_size.parse::<f64>().unwrap_or(0.0);
let filled = order.size_matched.parse::<f64>().unwrap_or(0.0);
qty > 0.0 && filled >= 0.0
} Try / catch
match build_ws_order_status_report(&instrument, &order, ...) {
Ok(report) => emit(report),
Err(e) if e.to_string().contains("invalid order quantity") => {
log::warn!("skipping order update with bad quantities size={:?} matched={:?}: {e:#}",
order.original_size, order.size_matched);
}
Err(e) => return Err(e),
} Prevention
- Range-check venue quantities (>0 original, >=0 matched) before consuming updates
- Treat empty size_matched as zero only for the documented FOK-cancel case
- Watch for venue API schema changes that shift quantity fields
- Validate fixtures in tests carry realistic positive sizes
When it happens
Trigger: An order-update with original_size "0" or empty-but-non-matching values, a negative size_matched from a malformed or schema-changed message, or a fixture/test message missing quantity fields.
Common situations: Polymarket API message-shape changes shifting quantity fields; partially-filled cancel messages with unexpected matched sizes; corrupted feed data; hand-written test fixtures with zero sizes.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- order price must be in (0, 1)
- Not a subscription channel: {kind}
- RTDS TWAP topic {:?} requires window_s={}, received {}
- conflicting RTDS TWAP observation topic={} symbol={} timesta
- Unsupported RTDS custom data type: {other}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/141ca57861cb9bd6.
Report an issue: GitHub.