{"record":{"id":"fde49b8674e5becb","repo":"FyroxEngine/Fyrox","slug":"there-s-no-message-sender-for-shared-handle-th","errorCode":null,"errorMessage":"There's no message sender for shared handle {}. The object won't be destroyed.","messagePattern":"There's no message sender for shared handle (.+?)\\. The object won't be destroyed\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"fyrox-ui/src/lib.rs","lineNumber":405,"sourceCode":"            self.sender = Some(\n                visitor\n                    .blackboard\n                    .get::<Sender<UiMessage>>()\n                    .expect(\"Ui message sender must be provided for correct deserialization!\")\n                    .clone(),\n            );\n        }\n\n        Ok(())\n    }\n}\n\nimpl Drop for RcUiNodeHandleInner {\n    fn drop(&mut self) {\n        if let Some(sender) = self.sender.as_ref() {\n            let _ = sender.send(UiMessage::for_widget(self.handle, WidgetMessage::Remove));\n        } else {\n            Log::warn(format!(\n                \"There's no message sender for shared handle {}. The object \\\n            won't be destroyed.\",\n                self.handle\n            ))\n        }\n    }\n}\n\n/// Reference counted handle to a widget. It is used to automatically destroy the widget it points\n/// to when the reference counter reaches zero. Its main usage in the library is to store handles\n/// to context menus that could be shared across multiple widgets.\n#[derive(Clone, Default, Visit, Reflect)]\n#[reflect(type_uuid = \"9111a53b-05dc-4c75-aab1-71d5b1c93311\")]\npub struct RcUiNodeHandle(Arc<Mutex<RcUiNodeHandleInner>>);\n\nimpl Debug for RcUiNodeHandle {\n    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {\n        let handle = self.0.safe_lock().handle;","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/FyroxEngine/Fyrox/blob/76c91aad8eca488ce527b1af707be8b3b24ad72d/fyrox-ui/src/lib.rs#L387-L423","documentation":"RcUiNodeHandle is a shared handle that, when dropped, sends a Remove widget message back to the UI via a stored message sender so the widget is destroyed. If the sender is None (handle created without a sender), the widget cannot be scheduled for destruction, the node leaks in the UI, and this warning is logged.","triggerScenarios":"Dropping an RcUiNodeHandle whose inner RcUiNodeHandleInner was constructed with sender: None — i.e. the handle was created through an API path that doesn't supply a UiMessage sender, then the last reference is dropped.","commonSituations":"Storing RcUiNodeHandles taken from widget contexts/builders where no sender is available, then letting the handle drop and noticing the widget still exists in the UI; holding handles across UI teardown so the sender is gone.","solutions":["Create/clone the shared handle through the API path that supplies a sender so Drop can send WidgetMessage::Remove.","Send WidgetMessage::Remove manually for the handle if you know the UI instance.","Verify the UI that owns the widget is still alive when the handle drops; teardown order may invalidate the sender path.","If leaking is intentional, ignore the warning or manage the widget lifetime explicitly."],"exampleFix":"// before\nlet handle = RcUiNodeHandle::new(node_handle, None); // no sender -> leak on drop\n// after\nlet handle = RcUiNodeHandle::new(node_handle, Some(ui_sender.clone()));\n// or, on cleanup:\nui.send_message(WidgetMessage::remove(node_handle));","handlingStrategy":"fallback","validationCode":"// Before dropping, ensure the widget will be removed\nif handle_needs_manual_cleanup {\n    ui.send_message(WidgetMessage::remove(node_handle));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Construct RcUiNodeHandle only through APIs that provide a message sender.","Keep the UI alive as long as shared handles exist.","Manually send WidgetMessage::Remove when you know the sender is unavailable.","Watch logs for this warning during teardown to spot leaked widgets."],"tags":["gui","memory-leak","lifecycle"],"backgroundTag":"missing-dependency","analyzedSha":"76c91aad8eca488ce527b1af707be8b3b24ad72d","analyzedAt":"2026-09-10T16:04:01.633Z","contentChangedAt":"2026-09-10T16:04:01.633Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}