nautechsystems/nautilus_trader · error · anyhow::Error

Failed to create price from limit_px: {e}

Error message

Failed to create price from limit_px: {e}

What it means

Raised in parse_order_status_report_from_basic when Price::from_decimal_dp fails converting the order's limit_px into a domain Price at the instrument's price precision, for orders whose status is not Filled/PartiallyFilled (open/resting orders). Price::from_decimal_dp fails when precision exceeds the fixed-point maximum, the value cannot be represented in the raw fixed-point range, or conversion overflows. This typically means limit_px from Hyperliquid is incompatible with the instrument's price_precision.

Source

Thrown at crates/adapters/hyperliquid/src/http/parse.rs:1018

    }

    if let Some(reduce_only) = order.reduce_only {
        report = report.with_reduce_only(reduce_only);
    }

    if let Some(reason) = status.rejection_reason() {
        report = report.with_cancel_reason(reason.to_string());
    }

    // Only set price for non-filled orders. For filled orders, the limit price is not
    // the execution price, and setting it would cause bogus inferred fills to be created
    // during reconciliation. Real fills arrive via the userEvents WebSocket channel.
    if !matches!(
        order_status,
        OrderStatus::Filled | OrderStatus::PartiallyFilled
    ) {
        let price = Price::from_decimal_dp(order.limit_px, price_precision)
            .map_err(|e| anyhow::anyhow!("Failed to create price from limit_px: {e}"))?;
        report = report.with_price(price);
    }

    if is_conditional && let Some(trigger_px) = order.trigger_px {
        let trigger_price = Price::from_decimal_dp(trigger_px, price_precision)
            .map_err(|e| anyhow::anyhow!("Failed to create trigger price: {e}"))?;
        report = report
            .with_trigger_price(trigger_price)
            .with_trigger_type(TriggerType::Default);
    }

    Ok(report)
}

/// Parses a `recentTrades` info entry into a [`TradeTick`].
///
/// Mirrors the field mapping of the WebSocket trade parser
/// [`parse_ws_trade_tick`](crate::websocket::parse::parse_ws_trade_tick): both the

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify limit_px in the raw response is a sane decimal and within the instrument's tick-size/precision; re-fetch instruments if the definition is stale
  2. Confirm the correct instrument (perp vs spot, correct asset) is being matched so price_precision is right
  3. Round/normalize limit_px to the instrument precision before parsing if you control the data path, or widen the instrument's price_precision in its definition
  4. Catch the error per-order and skip/degrade that report instead of failing the whole status sweep

Example fix

// before
let price = Price::from_decimal_dp(order.limit_px, price_precision)
    .map_err(|e| anyhow::anyhow!("Failed to create price from limit_px: {e}"))?;
// after
let price = Price::from_decimal_dp(order.limit_px, price_precision)
    .map_err(|e| anyhow::anyhow!("Failed to create price from limit_px {}: {e}", order.limit_px))?;
Defensive patterns

Strategy: validation

Validate before calling

// Python: check px sanity before calling the API
if px <= 0 or len(str(px).split('.')[-1]) > expected_price_precision:
    raise ValueError(f"limit_px {px} not representable at precision {expected_price_precision}")

Try / catch

try:
    reports = client.request_order_status_reports(...)
except ValueError as e:
    if "limit_px" in str(e):
        log.warning("unrepresentable limit_px, skipping order: %s", e)
    else:
        raise

Prevention

When it happens

Trigger: Calling any order-status report request (by order id, client order id, or open orders for dexes) for a non-filled order whose limit_px has more decimals than the instrument's price_precision, is a sentinel/huge value, or cannot be scaled to PriceRaw without overflow.

Common situations: Stale instrument definitions whose price_precision doesn't match the venue (venue changed tick size); spot vs perp instrument confusion; hyperliquid returning scientific-notation or sub-tick prices for special orders (e.g. closing-liquidation orders with extreme px).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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