{"record":{"id":"27ebc9fc392ae75a","repo":"nautechsystems/nautilus_trader","slug":"evidence-side-actual-does-not-match-known-orde","errorCode":null,"errorMessage":"{evidence} side {actual} does not match known order side {expected}","messagePattern":"(.+?) side (.+?) does not match known order side (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/reconciliation.rs","lineNumber":143,"sourceCode":"        mut self,\n        expected_order_side: Option<OrderSide>,\n    ) -> Self {\n        self.expected_order_side = if self.venue_order_id.is_some() {\n            expected_order_side\n        } else {\n            None\n        };\n        self\n    }\n}\n\nfn validate_expected_order_side(\n    expected: Option<OrderSide>,\n    actual: OrderSide,\n    evidence: &str,\n) -> anyhow::Result<()> {\n    if let Some(expected) = expected {\n        anyhow::ensure!(\n            actual == expected,\n            \"{evidence} side {actual} does not match known order side {expected}\",\n        );\n    }\n    Ok(())\n}\n\nfn validate_target_trade_role(\n    trade: &PolymarketTradeReport,\n    venue_order_id: VenueOrderId,\n) -> anyhow::Result<bool> {\n    let target_is_taker = trade.taker_order_id == venue_order_id.as_str();\n    let target_maker_occurrences = trade\n        .maker_orders\n        .iter()\n        .filter(|order| order.order_id == venue_order_id.as_str())\n        .count();\n    let target_is_maker = target_maker_occurrences > 0;","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/reconciliation.rs#L125-L161","documentation":"validate_expected_order_side cross-checks the side implied by trade/order evidence against the side already recorded for the known order. If a target trade's side (from classify_target_trade) contradicts the known order's side, the reconciliation cannot be trusted and this error is raised with the evidence label. It prevents mis-attributing fills to the wrong order side.","triggerScenarios":"classify_target_trade encounters a fill/trade whose BUY/SELL side differs from the side stored on the matched order — e.g. matching a trade to the wrong order, a venue reporting taker side vs maker side inconsistently, or stale order state after a manual position change.","commonSituations":"Venue webhooks reporting the counterparty side; two open orders on opposite sides with overlapping fills being mixed up; cache holding an outdated order after a modify.","solutions":["Log the evidence string and both sides to identify which order the trade was matched against.","Fix the trade-to-order matching logic in classify_target_trade (match on order ID/volume first).","Refresh cached order state from the venue to rule out a stale recorded side."],"exampleFix":"// before\nlet trade = pick_any_trade(fills); // may match wrong order\nvalidate_expected_order_side(order.side(), trade.side, \"target-trade\")?;\n// after\nlet trade = fills.iter().find(|t| t.order_id == order.venue_order_id())\n    .context(\"no fill for this order\")?;\nvalidate_expected_order_side(order.side(), trade.side, \"target-trade\")?;","handlingStrategy":"validation","validationCode":"if let Some(expected) = order.side() {\n    if trade.side != expected { return Err(anyhow!(\"side mismatch for order {:?}\", order.venue_order_id())); }\n}","typeGuard":null,"tryCatchPattern":"match classify_target_trade(trades, &order) {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"does not match known order side\") => { log::warn!(\"side mismatch: {e}; refreshing order state\"); refresh_order_from_venue(order.venue_order_id())? }\n    Err(e) => return Err(e),\n}","preventionTips":["Match trades to orders by venue order ID, not by heuristic","Refresh cached order state before reconciliation","Be explicit about venue side-reporting conventions (maker vs taker)"],"tags":["rust","reconciliation","order-side","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}