nautechsystems/nautilus_trader · error

trade {} trader_side {:?} contradicts target order {venue_or

Error message

trade {} trader_side {:?} contradicts target order {venue_order_id} participant role

What it means

After determining the target order's role in the trade (maker or taker), the code cross-checks the trade's declared trader_side field. This error fires when the declared side (Maker/Taker) contradicts the order's actual participant role in the trade — the provider data is internally inconsistent.

Source

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

    venue_order_id: VenueOrderId,
) -> anyhow::Result<bool> {
    let target_is_taker = trade.taker_order_id == venue_order_id.as_str();
    let target_maker_occurrences = trade
        .maker_orders
        .iter()
        .filter(|order| order.order_id == venue_order_id.as_str())
        .count();
    let target_is_maker = target_maker_occurrences > 0;
    if !target_is_taker && !target_is_maker {
        return Ok(false);
    }
    anyhow::ensure!(
        usize::from(target_is_taker) + target_maker_occurrences == 1,
        "target order {venue_order_id} appears more than once in trade {}",
        trade.id,
    );
    let declared_maker = trade.trader_side == PolymarketLiquiditySide::Maker;
    anyhow::ensure!(
        declared_maker == target_is_maker,
        "trade {} trader_side {:?} contradicts target order {venue_order_id} participant role",
        trade.id,
        trade.trader_side,
    );
    Ok(true)
}

fn validate_maker_order_side(
    trade: &PolymarketTradeReport,
    maker_order: &PolymarketMakerOrder,
) -> anyhow::Result<OrderSide> {
    let derived_side = determine_order_side(
        trade.trader_side,
        trade.side,
        trade.asset_id.as_str(),
        maker_order.asset_id.as_str(),
    );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the trade payload and compare trade.trader_side against the order's position in maker_orders vs taker fields.
  2. Re-fetch the trade from the provider API to rule out a stale or mid-update record.
  3. Check for recent Polymarket API schema changes affecting trader_side semantics and update parsing.
  4. Drop the inconsistent trade from reconciliation and surface it for manual review.

Example fix

// before
anyhow::ensure!(declared_maker == target_is_maker, ...);
// after: detect and skip contradictory trades upstream
if (trade.trader_side == PolymarketLiquiditySide::Maker) != target_is_maker {
    warn!("trade {} has contradictory trader_side; skipping", trade.id);
    return Ok(false);
}
Defensive patterns

Strategy: validation

Validate before calling

fn trader_side_consistent(trade: &Trade, vid: &str) -> bool {
    let is_maker = trade.maker_orders.iter().any(|o| o.order_id == vid);
    (trade.trader_side == PolymarketLiquiditySide::Maker) == is_maker
}

Type guard

fn declared_side_matches_role(trade: &Trade, vid: &str) -> bool {
    let role_is_maker = trade.maker_orders.iter().any(|o| o.order_id == vid);
    match trade.trader_side {
        PolymarketLiquiditySide::Maker => role_is_maker,
        PolymarketLiquiditySide::Taker => !role_is_maker,
    }
}

Try / catch

match classify_target_trade(&trade, &venue_order_id) {
    Ok(is_target) => { /* proceed */ }
    Err(e) if e.to_string().contains("contradicts") => warn!("inconsistent trade skipped: {e}"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: classify_target_trade -> validate_target_trade_role sees target_is_maker true while trade.trader_side is not Maker (or vice versa), e.g. trade.trader_side == Taker but the venue order id only appears in the maker list.

Common situations: Provider data-api returning inconsistent trader_side after a trade format change; a trade where the authenticated trader fields are mismatched to the order list; cached/stale trade objects merged incorrectly.

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