{"record":{"id":"f136f68285c54d34","repo":"nautechsystems/nautilus_trader","slug":"venue-leg-fills-cannot-be-represented-exactly","errorCode":null,"errorMessage":"venue-leg fills cannot be represented exactly","messagePattern":"venue-leg fills cannot be represented exactly","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/reconciliation.rs","lineNumber":81,"sourceCode":") -> anyhow::Result<(Quantity, Quantity)> {\n    let mut filled = Decimal::ZERO;\n\n    for event in order.events() {\n        match event {\n            OrderEventAny::Filled(event) if event.venue_order_id == venue_order_id => {\n                filled += event.last_qty.as_decimal();\n            }\n            OrderEventAny::FillVoided(event) if event.venue_order_id == venue_order_id => {\n                filled -= event.voided_qty.as_decimal();\n            }\n            _ => {}\n        }\n    }\n\n    anyhow::ensure!(filled >= Decimal::ZERO, \"venue-leg fills are negative\");\n    let current_leg_filled = Quantity::from_decimal_dp(filled, size_precision)\n        .context(\"venue-leg fills exceed quantity precision\")?;\n    anyhow::ensure!(\n        current_leg_filled.as_decimal() == filled,\n        \"venue-leg fills cannot be represented exactly\"\n    );\n    let filled_before = order\n        .filled_qty()\n        .checked_sub(current_leg_filled)\n        .context(\"current venue-leg fills exceed cumulative fills\")?;\n    let leg_quantity = order\n        .quantity()\n        .checked_sub(filled_before)\n        .context(\"fills before current venue leg exceed logical quantity\")?;\n    Ok((filled_before, leg_quantity))\n}\n\n/// Shared context for trade-to-fill-report conversion.\npub(crate) struct FillContext<'a> {\n    pub account_id: AccountId,\n    pub user_address: &'a str,","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/reconciliation.rs#L63-L99","documentation":"After computing the venue-leg filled Decimal, it is converted to a Quantity at the order's size_precision. If the value cannot be represented exactly at that precision (Quantity::from_decimal_dp rounds/fails), the subsequent equality check between the Quantity and the original Decimal fails, raising this error to avoid silently rounding fill data.","triggerScenarios":"Reconstructing fills (via load_orders_from_cache, query_order_command, generate_order_status_report(s)_impl) where summed event quantities carry more decimal places than the order's size_precision — e.g. partial fills with 4 dp against a 2 dp instrument definition.","commonSituations":"Instrument size_precision misconfigured vs the venue's actual fill increments; manual/odd lot fills from the venue exceeding the declared precision; stale instrument definitions after a venue change.","solutions":["Align the instrument's size_precision with the venue's actual fill size increments.","Log the raw filled Decimal and compare with the order's size_precision to confirm the mismatch.","Round venue fills to the instrument's tick size at ingestion so sums remain exactly representable."],"exampleFix":"// before\nlet size_precision = instrument.size_precision(); // 2 dp\nlet qty = Quantity::from_decimal_dp(filled, size_precision)?; // filled has 4 dp\n// after\nlet size_precision = 4; // match venue fill increments\nlet qty = Quantity::from_decimal_dp(filled, size_precision)?;","handlingStrategy":"validation","validationCode":"let dp = filled.scale();\nif dp as u32 > size_precision { return Err(anyhow!(\"fill precision {dp} exceeds instrument precision {size_precision}\")); }","typeGuard":"fn fits_precision(d: Decimal, precision: u8) -> bool { (d.scale() as u32) <= precision as u32 }","tryCatchPattern":"match Quantity::from_decimal_dp(filled, size_precision) {\n    Ok(q) => q,\n    Err(_) => { log::warn!(\"rounding fill {filled} to precision {size_precision}\"); Quantity::from_decimal_dp(filled.round_dp(size_precision), size_precision)? }\n}","preventionTips":["Keep instrument size_precision in sync with venue fill increments","Round venue fills to tick size at ingestion","Re-sync instrument definitions on venue updates"],"tags":["rust","reconciliation","precision","order-state"],"backgroundTag":"type-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}