FyroxEngine/Fyrox · warning
Widget `on_update` method is already registered!
Error message
Widget {node_handle} `on_update` method is already registered! What it means
During widget registration the registry inserts the node handle into the on_update set when the widget's need_update flag is true. Inserting an already-present handle means the same widget is registered twice, producing this warning. It flags duplicate registration of an updatable widget; the registry prevents double updates but the call site has a bug.
Solutions
- Register each widget exactly once; audit the add-node path for double calls.
- Always pair register with unregister on widget removal so handles don't persist in the on_update set.
- Add a registration guard/flag around repeated UI rebuilds.
- If harmless in your flow, the warning can be tolerated, but fix the duplicate to avoid future routing bugs.
Example fix
// before let widget = MyWidgetBuilder::new(...).build(ctx); ui.register(widget.clone()); ui.register(widget); // duplicate // after let widget = MyWidgetBuilder::new(...).build(ctx); ui.register(widget); // single registration
Defensive patterns
Strategy: validation
Validate before calling
let newly = self.registered_update_handles.insert(node.handle());
if newly { ui.register_widget(node); } Prevention
- Ensure each updatable widget is registered exactly once.
- Unregister on remove so the on_update set stays consistent.
- Centralize UI registration in one function to avoid scattered duplicate calls.
- On UI rebuild, reset registry state alongside widget handles.
When it happens
Trigger: Calling WidgetMethodsRegistry::register (via the UI node registration flow) twice for a widget whose Control::need_update is true — e.g. re-inserting a node, builder double-registration, or plugin reload re-registering without unregistering.
Common situations: Widgets with per-frame update logic (Control::on_update) added to the UI twice; re-registering after a remove that skipped unregister; game code rebuilding UI without cleaning registry state.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Widget `preview_message` method is already registered!
- Widget `handle_os_event` method is already registered!
- There's no message sender for shared handle
- Window name is empty, wrong widget will be used as a tile…
- Floating window name is empty, wrong widget will be used as…
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/20a1c160960c9106.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-ui/src/lib.rs:673
handle_os_event: FxHashSet<Handle<UiNode>>,
}
impl WidgetMethodsRegistry {
fn register<T: Control + ?Sized>(&mut self, node: &T) {
let node_handle = node.handle();
if node.preview_messages && !self.preview_message.insert(node_handle) {
Log::warn(format!(
"Widget {node_handle} `preview_message` method is already registered!"
));
}
if node.handle_os_events && !self.handle_os_event.insert(node_handle) {
Log::warn(format!(
"Widget {node_handle} `handle_os_event` method is already registered!"
));
}
if node.need_update && !self.on_update.insert(node_handle) {
Log::warn(format!(
"Widget {node_handle} `on_update` method is already registered!"
));
}
}
fn unregister<T: Control + ?Sized>(&mut self, node: &T) {
let node_handle = node.handle();
self.preview_message.remove(&node_handle);
self.on_update.remove(&node_handle);
self.handle_os_event.remove(&node_handle);
}
}
/// A set of switches that allows you to disable a particular step of UI update pipeline.
#[derive(Clone, PartialEq, Eq, Default)]
pub struct UiUpdateSwitches {
/// A set of nodes that will be updated, everything else won't be updated.View on GitHub (pinned to 76c91aad8e)