{"record":{"id":"5face668b20b6db6","repo":"nautechsystems/nautilus_trader","slug":"noid-does-not-match-new-order-oid","errorCode":null,"errorMessage":"noid '{}' does not match new order oid '{}'","messagePattern":"noid '(.+?)' does not match new order oid '(.+?)'","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/architect_ax/src/execution.rs","lineNumber":1464,"sourceCode":"    {\n        return Some(metadata);\n    }\n\n    if let Some(cid) = order.cid\n        && let Some(client_order_id) = caches.cid_to_client_order_id.get(&cid)\n        && let Some(metadata) = caches.orders_metadata.get(&*client_order_id)\n    {\n        return Some(metadata);\n    }\n\n    None\n}\n\npub(crate) fn replacement_venue_order_id(\n    message: &crate::websocket::messages::AxWsOrderReplaced,\n) -> anyhow::Result<VenueOrderId> {\n    if message.noid != message.no.oid {\n        anyhow::bail!(\n            \"noid '{}' does not match new order oid '{}'\",\n            message.noid,\n            message.no.oid\n        );\n    }\n\n    VenueOrderId::new_checked(&message.noid).map_err(anyhow::Error::from)\n}\n\npub(crate) fn create_order_accepted(\n    order: &AxWsOrder,\n    event_ts: i64,\n    event_tn: i64,\n    caches: &OrdersCaches,\n    account_id: AccountId,\n    clock: &'static AtomicTime,\n) -> Option<OrderAccepted> {\n    let venue_order_id = VenueOrderId::new(&order.oid);","sourceCodeStart":1446,"sourceCodeEnd":1482,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/architect_ax/src/execution.rs#L1446-L1482","documentation":"A consistency check on the venue's orders-websocket Replace event: AxWsOrderReplaced carries both a top-level noid (new order id) and a nested new-order object no whose oid should identify the same order. If they differ, the adapter cannot tell which id is authoritative for the replacement, so it refuses to mint the new VenueOrderId and the replace cannot be applied to local state. This is a venue-protocol invariant violation, not something your order parameters cause.","triggerScenarios":"Architect changes the AxWsOrderReplaced schema or ships a bug where noid and no.oid disagree; a partial/malformed JSON message decoded into divergent fields. Triggered purely by inbound WS traffic after a successful order modify.","commonSituations":"Right after an AX API update that altered replace-event semantics; extremely rare otherwise. Appears as order-modify events failing to update local state in logs.","solutions":["Capture the raw websocket frame (debug logs) and report the mismatch to Architect support","Check the nautilus_trader changelog / AX API release notes for schema changes and update the adapter if a new version handles it","As a stopgap, reconcile local order state from the REST order snapshot after a replace instead of the event"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// replacement_venue_order_id returns Result; on Err, reconcile from REST\nlet new_vid = match replacement_venue_order_id(&replaced_msg) {\n    Ok(v) => v,\n    Err(e) => {\n        log::error!(\"replace event inconsistent ({e}); reconciling via REST snapshot\");\n        reconcile_orders_from_rest().await?;\n        return Ok(());\n    }\n};","preventionTips":["Run periodic REST order-state reconciliation so a bad WS event cannot desync you permanently","Capture raw AX WS frames at debug level in production for vendor-bug reports","Pin adapter versions against tested AX API versions and regression-test after venue updates"],"tags":["architect-ax","websocket","order-replace","protocol-validation","rust"],"backgroundTag":"venue-message-schema-mismatch","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}