{"record":{"id":"d6dacae266680e7d","repo":"nautechsystems/nautilus_trader","slug":"failed-to-apply-ibordertags-because-ib-order-json","errorCode":null,"errorMessage":"Failed to apply IBOrderTags because IB order JSON is not an object","messagePattern":"Failed to apply IBOrderTags because IB order JSON is not an object","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/execution/transform/tags.rs","lineNumber":102,"sourceCode":"            anyhow::bail!(\"Invalid IBOrderTags field {field}: {value}\");\n        };\n\n        for (field, value) in updates.drain(..) {\n            apply_order_field_update(ib_order, &mut order_value, &field, value)?;\n        }\n    }\n\n    Ok(())\n}\n\nfn apply_order_field_update(\n    ib_order: &mut IBOrder,\n    order_value: &mut Value,\n    field: &str,\n    value: Value,\n) -> 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                );","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/execution/transform/tags.rs#L84-L120","documentation":"apply_order_field_update maintains a parallel serde_json::Value view of the IBOrder so it can insert-then-restore on failure. If that Value is not a JSON object (an internal invariant — it is initialized from the serialized IBOrder), the update cannot proceed and the function bails.","triggerScenarios":"apply_ib_order_tag_overlay -> apply_order_field_update when order_value.as_object_mut() returns None. Should only occur if the serialized IBOrder is not an object, e.g. a corrupted or non-struct serialization of IBOrder.","commonSituations":"Rare; points to an internal inconsistency such as IBOrder serializing to a non-object (custom Serialize impl, version drift between serializer and tag-applier).","solutions":["Verify the IBOrder serializes to a JSON object (custom Serialize impls or newtype wrappers break this)\nUpdate the adapter: if IBOrder's serialization changed, the tag-applier's assumption must be fixed in the crate\nReport as a bug if stock IBOrder triggers it — this is an internal invariant violation"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match nautilus_order_to_ib_order(...) {\n    Err(e) if e.to_string().contains(\"IB order JSON is not an object\") => {\n        // internal invariant broken; log full order context and report a bug\n        tracing::error!(\"adapter invariant violated: {e:#}\");\n    }\n    r => r?,\n}","preventionTips":["Do not customize IBOrder's serialization","Keep the adapter crate up to date with any IBOrder struct changes","Treat this error as a bug report trigger, not a recoverable condition"],"tags":["interactive-brokers","json","internal","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-14T05:17:10.506Z"}