nautechsystems/nautilus_trader · error

replacement venue-leg price {:?} does not match signed price

Error message

replacement venue-leg price {:?} does not match signed price {}

What it means

During replacement-leg promotion, the venue report's price must equal the signed promotion price (as Some). This ensure! fires when the venue leg price differs from the price the adapter signed, indicating divergence between submitted replacement price and live venue state.

Source

Thrown at crates/adapters/polymarket/src/execution/reports.rs:721

            let promotion = self
                .ws_dispatch_state
                .lock()
                .pending_modify_promotion(report.venue_order_id);
            let Some(promotion) = promotion else {
                continue;
            };

            let context = self
                .order_contexts
                .get(&promotion.old_venue_order_id)
                .context("pending modification has no old-leg context")?;
            anyhow::ensure!(
                report.quantity == promotion.leg_quantity,
                "replacement venue-leg quantity {} does not match signed quantity {}",
                report.quantity,
                promotion.leg_quantity,
            );
            anyhow::ensure!(
                report.price == Some(promotion.price),
                "replacement venue-leg price {:?} does not match signed price {}",
                report.price,
                promotion.price,
            );
            anyhow::ensure!(
                report.order_side == Some(context.identity.order_side),
                "replacement venue-leg side {:?} does not match logical order side {}",
                report.order_side,
                context.identity.order_side,
            );
            let cached_order = self
                .core
                .cache()
                .order_owned(&promotion.client_order_id)
                .context("pending modification has no cached logical order")?;

            if report.order_status == OrderStatus::Rejected {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Handle market-order replacements separately (price may legitimately be None)
  2. Re-poll; venue state may still be settling after replace
  3. Verify price Decimal precision when constructing the promotion payload
  4. Check for third-party modification of the order on the venue

Example fix

// before
anyhow::ensure!(report.price == Some(promotion.price), ...);
// after
match order.order_type() {
    OrderType::Market => {} // no price expected
    OrderType::Limit => anyhow::ensure!(report.price == Some(promotion.price), ...),
    _ => {}
}
Defensive patterns

Strategy: validation

Validate before calling

if order.order_type() == OrderType::Limit {
    anyhow::ensure!(promotion.price == order.price().context("limit order missing price")?, "promotion price mismatch");
}

Type guard

fn promotion_price_valid(promotion: &Promotion, report: &OrderStatusReport) -> bool {
    report.price == Some(promotion.price)
}

Try / catch

match report.price {
    Some(p) if p != promotion.price => warn!("replace price diverged; re-poll before promoting"),
    None if order.order_type() == OrderType::Limit => warn!("venue returned no price for limit leg"),
    _ => {},
}

Prevention

When it happens

Trigger: generate_order_status_reports promotes a pending modification and the polled report.price is None or differs from promotion.price.

Common situations: Market order replacement (no price) being validated as a limit; venue amended the price before the status poll; price formatting/precision differences between signed payload and venue echo.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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