{"record":{"id":"85d1ef7adf9ed195","repo":"nautechsystems/nautilus_trader","slug":"cannot-register-oms-type-e","errorCode":null,"errorMessage":"Cannot register OMS type: {e}","messagePattern":"Cannot register OMS type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/node/mod.rs","lineNumber":2722,"sourceCode":"        // Capture strategy-owned values before adding the strategy, which moves it\n        let strategy_id = self\n            .kernel\n            .trader\n            .borrow()\n            .prepare_strategy_for_registration(&mut strategy)?;\n        let oms_type = StrategyNative::strategy_core(&strategy).config.oms_type;\n        let instrument_ids = strategy.external_order_instrument_ids().unwrap_or_default();\n\n        if !instrument_ids.is_empty() {\n            self.register_external_order_claims(strategy_id, &instrument_ids)?;\n        }\n\n        let mut exec_engine = match oms_type\n            .map(|_| {\n                self.kernel\n                    .exec_engine\n                    .try_borrow_mut()\n                    .map_err(|e| anyhow::anyhow!(\"Cannot register OMS type: {e}\"))\n            })\n            .transpose()\n        {\n            Ok(exec_engine) => exec_engine,\n            Err(e) => {\n                if !instrument_ids.is_empty()\n                    && let Err(rollback_error) =\n                        self.rollback_external_order_claims(strategy_id, &instrument_ids)\n                {\n                    anyhow::bail!(\n                        \"{e}; failed to roll back external order claims for {strategy_id}: {rollback_error}\"\n                    );\n                }\n                return Err(e);\n            }\n        };\n\n        if let Err(add_error) = self.kernel.trader.borrow_mut().add_strategy(strategy) {","sourceCodeStart":2704,"sourceCodeEnd":2740,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/node/mod.rs#L2704-L2740","documentation":"This error wraps a `RefCell::try_borrow_mut` failure on the live node's kernel exec engine. The kernel stores `exec_engine` in a `RefCell` to allow shared access across the node; if the engine is already mutably (or even immutably) borrowed by another call on the same thread, `try_borrow_mut` returns `Err` and the node raises this message. It is a re-entrancy / aliasing violation, not a domain problem with the OMS type itself.","triggerScenarios":"Calling `add_strategy` while the kernel's `exec_engine` RefCell is already borrowed — e.g. calling `add_strategy` from inside a callback that itself holds a borrow of the exec engine, or calling it while a previous registration on the same thread is still in scope.","commonSituations":"Registering a strategy from within an actor/event handler on the live node; nested `add_strategy` calls in async code where a previous borrow hasn't been dropped; holding `node.kernel.exec_engine.borrow()` in user code before calling `add_strategy`.","solutions":["Ensure no other borrow of the kernel exec engine is alive on the current thread when calling `add_strategy` (drop `borrow()`/`borrow_mut()` guards first).","Move strategy registration to node startup, before the trading loop/event callbacks begin.","If calling from a callback, defer registration (queue it and register from the outer scope).","Inspect the `e` in the message: Pyo3 borrows print the location of the conflicting borrow, which identifies the holder."],"exampleFix":"// before\nlet engine = node.kernel.exec_engine.borrow();\nnode.add_strategy(strategy, ...)?;\n// after\ndrop(node.kernel.exec_engine.borrow()); // release before registering\nnode.add_strategy(strategy, ...)?;","handlingStrategy":"try-catch","validationCode":"// Check the exec engine borrow is free before registering\nif node.kernel.exec_engine.try_borrow().is_err() {\n    return Err(anyhow::anyhow!(\"exec engine already borrowed; defer add_strategy\"));\n}","typeGuard":null,"tryCatchPattern":"match node.add_strategy(strategy, instrument_ids) {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"Cannot register OMS type\") => {\n        // retry after borrows are released / defer to startup phase\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never hold `borrow()`/`borrow_mut()` guards on kernel fields across calls that register components","Register strategies/actors during node setup, before the event loop runs","Avoid calling add_strategy from inside event or data callbacks","Read the wrapped Pyo3 borrow message to locate the conflicting borrow site"],"tags":["rust","refcell","borrow-conflict","live-node"],"backgroundTag":"refcell-already-borrowed","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"}