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
- Log the full raw order message to see what venue actually sent for price
- Skip/ignore reports for message types that legitimately carry no price (e.g. pure cancels) instead of building a report
- Update the parsing/mapping in the adapter if the venue schema changed and price moved fields
- 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
- Treat venue prices as untrusted input; range-check before use
- Recognize placeholder-price message shapes (market/FOK records) and skip them upstream
- Log full raw payloads on rejection to catch venue schema changes early
- Pin and review the adapter against Polymarket API version updates
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
- invalid order quantity
- 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/27aac0ec69ddee51.
Report an issue: GitHub.