nautechsystems/nautilus_trader · error · anyhow::Error

order price must be in (0, 1)

Error message

order price must be in (0, 1)

What it means

build_ws_order_status_report() converts a venue order-update message into an OrderStatusReport and enforces that the venue-reported order price, parsed as an exact decimal, lies strictly between 0 and 1 — Polymarket prices are probabilities in the open interval (0, 1). A price of 0, 1, or outside that range means the venue message is malformed, uses a placeholder price (e.g. for market orders), or a parsing assumption broke, so the report is rejected rather than propagated with bogus data.

Source

Thrown at crates/adapters/polymarket/src/websocket/dispatch.rs:1376

fn build_ws_order_status_report(
    order: &PolymarketUserOrder,
    status: &PolymarketUserOrderStatus,
    order_type: PolymarketOrderType,
    instrument: &InstrumentAny,
    account_id: AccountId,
    ts_event: UnixNanos,
    ts_init: UnixNanos,
) -> anyhow::Result<OrderStatusReport> {
    let venue_order_id = VenueOrderId::from(order.id.as_str());
    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,
    )?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the full raw order message to see what venue actually sent for price
  2. Skip/ignore reports for message types that legitimately carry no price (e.g. pure cancels) instead of building a report
  3. Update the parsing/mapping in the adapter if the venue schema changed and price moved fields
  4. If your own code produces the message (tests/fixtures), supply a valid price strictly between 0 and 1

Example fix

// before
anyhow::ensure!(
    price_dec > Decimal::ZERO && price_dec < Decimal::ONE,
    "order price must be in (0, 1)"
);
// after — treat priceless message shapes as non-reportable upstream
if order.price.is_empty() || order.price == "0" {
    return Ok(None); // venue sent a placeholder price; no report to emit
}
anyhow::ensure!(
    price_dec > Decimal::ZERO && price_dec < Decimal::ONE,
    "order price must be in (0, 1)"
);
Defensive patterns

Strategy: validation

Validate before calling

// validate before accepting a venue order update into your book/state
let p: f64 = order.price.parse()?;
if !(p > 0.0 && p < 1.0) {
    // skip or quarantine the message; do not build a report
    return Ok(None);
}

Type guard

fn has_valid_venue_price(order: &WsOrder) -> bool {
    order.price.parse::<f64>().map(|p| p > 0.0 && p < 1.0).unwrap_or(false)
}

Try / catch

match build_ws_order_status_report(&instrument, &order, ...) {
    Ok(report) => emit(report),
    Err(e) if e.to_string().contains("order price must be in (0, 1)") => {
        log::warn!("skipping order update with invalid venue price {:?}: {e:#}", order.price);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A Polymarket WebSocket order-update carrying price "0" or "1" (e.g. zero-price placeholder on certain market-order/FOK records), an unparseable or shifted field mapped into order.price, or a venue schema change that moves the real price elsewhere.

Common situations: Market/FOK orders whose captured message has no meaningful limit price; new venue message fields after an API update; asset-level data corruption on the feed; tests feeding edge-case fixtures with price 0/1.

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


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