{"record":{"id":"24cc32f77b28732b","repo":"nautechsystems/nautilus_trader","slug":"failed-to-restore-ib-order-json-after-invalid-ibor","errorCode":null,"errorMessage":"Failed to restore IB order JSON after invalid IBOrderTags field: {field}","messagePattern":"Failed to restore IB order JSON after invalid IBOrderTags field: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/execution/transform/tags.rs","lineNumber":118,"sourceCode":") -> anyhow::Result<()> {\n    let Some(order_obj) = order_value.as_object_mut() else {\n        anyhow::bail!(\"Failed to apply IBOrderTags because IB order JSON is not an object\");\n    };\n\n    if !order_obj.contains_key(field) {\n        anyhow::bail!(\"Unsupported IBOrderTags field: {field}\");\n    }\n\n    let previous = order_obj.insert(field.to_string(), value);\n\n    match serde_json::from_value::<IBOrder>(order_value.clone()) {\n        Ok(updated_order) => {\n            *ib_order = updated_order;\n            Ok(())\n        }\n        Err(e) => {\n            let Some(order_obj) = order_value.as_object_mut() else {\n                anyhow::bail!(\n                    \"Failed to restore IB order JSON after invalid IBOrderTags field: {field}\"\n                );\n            };\n\n            match previous {\n                Some(previous) => order_obj.insert(field.to_string(), previous),\n                None => order_obj.remove(field),\n            };\n            Err(anyhow::anyhow!(\"Invalid IBOrderTags field {field}: {e}\"))\n        }\n    }\n}\n\nfn sync_order_field(\n    order_value: &mut Value,\n    field: &str,\n    ib_order: &IBOrder,\n) -> anyhow::Result<()> {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/execution/transform/tags.rs#L100-L136","documentation":"When a tag value fails IBOrder deserialization, apply_order_field_update tries to restore the previous value in the JSON mirror. If that mirror is no longer an object at restore time, the original IBOrder cannot be safely restored, so it bails to avoid returning a half-mutated order.","triggerScenarios":"apply_order_field_update: serde_json::from_value::<IBOrder>(order_value.clone()) fails (the inserted value has the wrong type/shape for the field), and then order_value.as_object_mut() also returns None during the restore path.","commonSituations":"Follows error 864's root cause: a non-object serialized IBOrder combined with a tag value that fails validation; indicates both a bad tag value and a broken internal JSON mirror.","solutions":["Fix the tag value so it deserializes into IBOrder (correct type for the field) — this avoids the restore path entirely\nEnsure IBOrder serializes to a JSON object (no custom newtype Serialize)\nClone IBOrder before applying tags and discard on failure instead of relying on the JSON-mirror restore"],"exampleFix":"// before\n{\"order_ref\": 12345} // number where string expected\n// after\n{\"order_ref\": \"my-strategy-1\"}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let snapshot = ib_order.clone();\nif let Err(e) = apply_ib_order_tags(&mut ib_order, &tags) {\n    ib_order = snapshot; // restore independently of the adapter's internal restore\n    return Err(e);\n}","preventionTips":["Snapshot the IBOrder before applying tags so you can restore regardless of internal failure mode","Ensure tag values deserialize cleanly into IBOrder (correct types)","Report non-object serialization of IBOrder as a bug"],"tags":["interactive-brokers","json","state-corruption","rust"],"backgroundTag":"internal-invariant-violation","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"}