bevyengine/bevy · error
Component already has an on_add hook
Error message
Component already has an on_add hook
What it means
Panic in ComponentLifecycleHook registration (on_add): try_on_add returned None because the component's lifecycle storage already holds an on_add hook. Registering a second hook for the same event would silently drop one, so the builder method uses expect as a guard against double registration.
Source
Thrown at crates/bevy_ecs/src/lifecycle.rs:189
self.on_remove(hook);
}
if let Some(hook) = C::on_despawn() {
self.on_despawn(hook);
}
self
}
/// Register a [`ComponentHook`] that will be run when this component is added to an entity.
/// An `on_add` hook will always run before `on_insert` hooks. Spawning an entity counts as
/// adding all of its components.
///
/// # Panics
///
/// Will panic if the component already has an `on_add` hook
pub fn on_add(&mut self, hook: ComponentHook) -> &mut Self {
self.try_on_add(hook)
.expect("Component already has an on_add hook")
}
/// Register a [`ComponentHook`] that will be run when this component is added (with `.insert`)
/// or replaced.
///
/// An `on_insert` hook always runs after any `on_add` hooks (if the entity didn't already have the component).
///
/// # Warning
///
/// The hook won't run if the component is already present and is only mutated, such as in a system via a query.
/// 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_insert` hook
pub fn on_insert(&mut self, hook: ComponentHook) -> &mut Self {
self.try_on_insert(hook)
.expect("Component already has an on_insert hook")View on GitHub (pinned to 396ca72708)
Solutions
- Register each hook kind once per component; consolidate logic into the existing hook closure
- Remove a prior .on_add(...) call or plugin that already registered the hook
- Use try_on_add to handle pre-existing hooks gracefully instead of panicking
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/bevy_ecs/src/lifecycle.rs:189 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/fed5db95d1268a30.
Report an issue: GitHub.