bevyengine/bevy · error
Component already has an on_despawn hook
Error message
Component already has an on_despawn hook
What it means
Panic in ComponentLifecycleHook registration (on_despawn): try_on_despawn found the on_despawn slot already occupied. Only one despawn hook per component is representable, and the expect makes accidental double registration loud rather than silently replacing the first hook.
Source
Thrown at crates/bevy_ecs/src/lifecycle.rs:250
/// 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> {
if self.on_add.is_some() {
return None;
}
self.on_add = Some(hook);
Some(self)
}
/// Attempt to register a [`ComponentHook`] that will be run when this component is added (with `.insert`)
///
/// This is a fallible version of [`Self::on_insert`].View on GitHub (pinned to 396ca72708)
Solutions
- Consolidate despawn-time logic into the single registered hook
- Search the dependency graph for competing .on_despawn(...) calls on this component
- Switch to try_on_despawn when overlap is legitimate
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/bevy_ecs/src/lifecycle.rs:250 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/327cf236a26e85a0.
Report an issue: GitHub.