{"record":{"id":"327cf236a26e85a0","repo":"bevyengine/bevy","slug":"component-already-has-an-on-despawn-hook","errorCode":null,"errorMessage":"Component already has an on_despawn hook","messagePattern":"Component already has an on_despawn hook","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_ecs/src/lifecycle.rs","lineNumber":250,"sourceCode":"    /// Register a [`ComponentHook`] that will be run when this component is removed from an entity.\n    /// Despawning an entity counts as removing all of its components.\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the component already has an `on_remove` hook\n    pub fn on_remove(&mut self, hook: ComponentHook) -> &mut Self {\n        self.try_on_remove(hook)\n            .expect(\"Component already has an on_remove hook\")\n    }\n\n    /// Register a [`ComponentHook`] that will be run for each component on an entity when it is despawned.\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the component already has an `on_despawn` hook\n    pub fn on_despawn(&mut self, hook: ComponentHook) -> &mut Self {\n        self.try_on_despawn(hook)\n            .expect(\"Component already has an on_despawn hook\")\n    }\n\n    /// Attempt to register a [`ComponentHook`] that will be run when this component is added to an entity.\n    ///\n    /// This is a fallible version of [`Self::on_add`].\n    ///\n    /// Returns `None` if the component already has an `on_add` hook.\n    pub fn try_on_add(&mut self, hook: ComponentHook) -> Option<&mut Self> {\n        if self.on_add.is_some() {\n            return None;\n        }\n        self.on_add = Some(hook);\n        Some(self)\n    }\n\n    /// Attempt to register a [`ComponentHook`] that will be run when this component is added (with `.insert`)\n    ///\n    /// This is a fallible version of [`Self::on_insert`].","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ecs/src/lifecycle.rs#L232-L268","documentation":"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.","triggerScenarios":"Thrown at crates/bevy_ecs/src/lifecycle.rs:250 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}