bevyengine/bevy · error
Component already has an on_remove hook
Error message
Component already has an on_remove hook
What it means
Panic in ComponentLifecycleHook registration (on_remove): the component already has an on_remove hook stored, so try_on_remove could not install the new one and the expect fired. Same single-slot Option storage guard as the other lifecycle events.
Source
Thrown at crates/bevy_ecs/src/lifecycle.rs:240
/// As a result, this needs to be combined with immutable components to serve as a mechanism for reliably updating indexes and other caches.
///
/// # Panics
///
/// Will panic if the component already has an `on_discard` hook
pub fn on_discard(&mut self, hook: ComponentHook) -> &mut Self {
self.try_on_discard(hook)
.expect("Component already has an on_discard hook")
}
/// Register a [`ComponentHook`] that will be run when this component is removed from an entity.
/// Despawning an entity counts as removing all of its components.
///
/// # Panics
///
/// Will panic if the component already has an `on_remove` hook
pub fn on_remove(&mut self, hook: ComponentHook) -> &mut Self {
self.try_on_remove(hook)
.expect("Component already has an on_remove hook")
}
/// Register a [`ComponentHook`] that will be run for each component on an entity when it is despawned.
///
/// # Panics
///
/// Will panic if the component already has an `on_despawn` hook
pub fn on_despawn(&mut self, hook: ComponentHook) -> &mut Self {
self.try_on_despawn(hook)
.expect("Component already has an on_despawn hook")
}
/// Attempt to register a [`ComponentHook`] that will be run when this component is added to an entity.
///
/// This is a fallible version of [`Self::on_add`].
///
/// Returns `None` if the component already has an `on_add` hook.
pub fn try_on_add(&mut self, hook: ComponentHook) -> Option<&mut Self> {View on GitHub (pinned to 396ca72708)
Solutions
- Register on_remove once; combine multiple concerns in one hook closure
- Trace which plugin or configure_hooks call registered the first hook and de-duplicate
- Use try_on_remove for cooperative registration
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/bevy_ecs/src/lifecycle.rs:240 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/f94fe403ebe64c1f.
Report an issue: GitHub.