nautechsystems/nautilus_trader · error

provider order quantity {} does not match cached order quant

Error message

provider order quantity {} does not match cached order quantity {}

What it means

validate_client_bound_order_quantity cross-checks a provider PolymarketOpenOrder's original_size against the expected Quantity from the client's cached order. Any exact-decimal inequality raises this anyhow error, naming both values, because the reconciliation cannot safely trust a provider order whose size disagrees with the local cache.

Source

Thrown at crates/adapters/polymarket/src/execution/reconciliation.rs:472

            },
        )
    })?;

    if let Some(requested_instrument_id) = requested_instrument_id {
        anyhow::ensure!(
            instrument.id() == requested_instrument_id,
            "{evidence} resolves to instrument {}, not requested instrument {requested_instrument_id}",
            instrument.id(),
        );
    }
    Ok(instrument)
}

pub(super) fn validate_client_bound_order_quantity(
    provider_order: &PolymarketOpenOrder,
    expected_quantity: Quantity,
) -> anyhow::Result<()> {
    anyhow::ensure!(
        expected_quantity.as_decimal() == provider_order.original_size,
        "provider order quantity {} does not match cached order quantity {}",
        provider_order.original_size,
        expected_quantity,
    );
    Ok(())
}

fn validate_client_bound_order_row(
    provider_order: &PolymarketOpenOrder,
    cached_order: &OrderAny,
    expected_quantity: Quantity,
    provider_expire_time: Option<UnixNanos>,
) -> anyhow::Result<()> {
    anyhow::ensure!(
        cached_order.order_side() == provider_order.side.into(),
        "provider order side {} does not match cached order side {}",
        provider_order.side,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-fetch the current provider order and update the local cache's original_size, then retry reconciliation.
  2. Ensure the cached order stores original (not remaining) size and that both use the same unit and Decimal scale.
  3. If the mismatch is a legit amend, process the provider modify event first so the cache is in sync before validating.
  4. Clear/rebuild the order cache if the snapshot is stale relative to provider state.

Example fix

// before
let cached_qty = Quantity::from(remaining_size); // wrong: remaining, not original
validate_client_bound_order_quantity(&provider_order, cached_qty)?;
// after
let cached_qty = Quantity::new(provider_order.original_size, instrument.size_precision);
validate_client_bound_order_quantity(&provider_order, cached_qty)?;
Defensive patterns

Strategy: validation

Validate before calling

fn sizes_match(provider: &PolymarketOpenOrder, expected: Quantity) -> bool {
    expected.as_decimal() == provider.original_size
}
// refresh cache before reconcile:
let provider_order = client.get_order(&venue_order_id).await?;

Type guard

fn is_consistent_with_cache(o: &PolymarketOpenOrder, cached: &OrderAny) -> bool {
    cached.quantity().as_decimal() == o.original_size
}

Try / catch

match validate_client_bound_order_quantity(&provider_order, expected_qty) {
    Err(e) if e.to_string().contains("does not match cached order quantity") => {
        rebuild_cache_from_provider(&provider_order.id).await?; // resync then retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: validate_client_bound_order_row during build_order_report_from_order, or handle_fok_rest_status when handling a FOK order resting status, pass an expected_quantity that differs from provider_order.original_size — e.g. partial fills recorded locally but not reflected in original_size, or size/quantity unit mismatch (shares vs contracts).

Common situations: Provider mutates original_size on amend/partial-fill while the local cache keeps the original; local cache updated with remaining size instead of original size; decimal scale differences (1.0 vs 1.00 are equal as Decimal, but 1 vs 1.000001 are not); restoring an old cache snapshot after a provider-side change.

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/cae951a99999b581. Report an issue: GitHub.