{"record":{"id":"60073d3c29a1fdca","repo":"nautechsystems/nautilus_trader","slug":"unknown-position-side","errorCode":null,"errorMessage":"unknown position_side","messagePattern":"unknown position_side","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/websocket/streams/dispatch.rs","lineNumber":1136,"sourceCode":"///\n/// # Errors\n///\n/// Returns an error when position IDs are enabled but the position side is missing or unknown.\npub(crate) fn make_venue_position_id(\n    use_position_ids: bool,\n    instrument_id: InstrumentId,\n    position_side: Option<BinancePositionSide>,\n) -> anyhow::Result<Option<PositionId>> {\n    if !use_position_ids {\n        return Ok(None);\n    }\n\n    let position_side = position_side.context(\"missing position_side\")?;\n    let side = match position_side {\n        BinancePositionSide::Long => \"LONG\",\n        BinancePositionSide::Short => \"SHORT\",\n        BinancePositionSide::Both => return Ok(None),\n        BinancePositionSide::Unknown => anyhow::bail!(\"unknown position_side\"),\n    };\n    Ok(Some(PositionId::new(format!(\"{instrument_id}-{side}\"))))\n}\n\n/// Dispatches exchange-generated order fills (liquidation, ADL, settlement).\n///\n/// Bundles the parsed `OrderStatusReport` and `FillReport` into a single\n/// `OrderWithFills` send so the engine creates the external order from the\n/// status report and applies the real fill (preserving `trade_id` and\n/// `commission`) instead of synthesizing one. Falls back to whichever report\n/// parsed if the other parser fails.\n///\n/// Skips events with zero fill quantity (pending liquidation notifications).\n#[expect(clippy::too_many_arguments)]\npub(crate) fn dispatch_exchange_generated_fill(\n    msg: &BinanceFuturesOrderUpdateMsg,\n    emitter: &ExecutionEventEmitter,\n    instrument_id: InstrumentId,","sourceCodeStart":1118,"sourceCodeEnd":1154,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/futures/websocket/streams/dispatch.rs#L1118-L1154","documentation":"make_venue_position_id builds a venue PositionId from the position_side field of exchange order updates. BinancePositionSide::Unknown has no mapping, so the function bails with 'unknown position_side'. Both and Long/Short have defined behavior (None and LONG/SHORT suffix).","triggerScenarios":"dispatch_order_update or dispatch_algo_update receives an order update whose positionSide deserializes to BinancePositionSide::Unknown (typically an unrecognized side string from the exchange) while position IDs are enabled.","commonSituations":"A new/renamed Binance positionSide value the adapter does not recognize; corrupted or non-standard payloads (e.g. from a test mock or API change); deserializer defaulting unknown enum variants to Unknown.","solutions":["Inspect the raw payload's positionSide value and confirm it is one of LONG, SHORT, BOTH.","Update the BinancePositionSide enum/deserializer if Binance added a new variant.","Fix mock/test payloads to emit valid positionSide values."],"exampleFix":"// before\n{\"positionSide\": \"BOTH \"} // unrecognized due to whitespace -> Unknown\n// after\n{\"positionSide\": \"BOTH\"} // valid: returns Ok(None) in one-way mode","handlingStrategy":"validation","validationCode":"fn known_position_side(raw: &str) -> bool {\n    matches!(raw, \"LONG\" | \"SHORT\" | \"BOTH\")\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"unknown position_side\") => {\n        tracing::error!(\"unrecognized positionSide in update: log raw payload and inspect\");\n    }\n    r => r?,\n}","preventionTips":["Log raw payloads when the adapter version predates a Binance enum change.","Keep the BinancePositionSide enum in sync with exchange API docs.","Sanitize mock/test payloads to emit only LONG/SHORT/BOTH."],"tags":["position-id","enum","websocket","binance-futures"],"backgroundTag":"invalid-enum-value","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"}