{"record":{"id":"86cdd5daad910f89","repo":"bevyengine/bevy","slug":"resource-entity-of-has-been-despawned-when","errorCode":null,"errorMessage":"Resource entity {} of {} has been despawned, when it's not supposed to be.","messagePattern":"Resource entity (.+?) of (.+?) has been despawned, when it's not supposed to be\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_ecs/src/resource.rs","lineNumber":150,"sourceCode":"    /// The [`ComponentId`] of the resource component (the _actual_ resource value component, not the [`IsResource`] component).\n    pub fn resource_component_id(&self) -> ComponentId {\n        self.0\n    }\n\n    pub(crate) fn on_insert(mut world: DeferredWorld, context: HookContext) {\n        let resource_component_id = world\n            .entity(context.entity)\n            .get::<Self>()\n            .unwrap()\n            .resource_component_id();\n\n        if let Some(original_entity) = world.resource_entities.get(resource_component_id) {\n            if !world.entities().contains(original_entity) {\n                let name = world\n                    .components()\n                    .get_name(resource_component_id)\n                    .expect(\"resource is registered\");\n                panic!(\n                    \"Resource entity {} of {} has been despawned, when it's not supposed to be.\",\n                    original_entity, name\n                );\n            }\n\n            if original_entity != context.entity {\n                // the resource already exists and the new one should be removed\n                world\n                    .commands()\n                    .entity(context.entity)\n                    .remove_by_id(resource_component_id);\n                world\n                    .commands()\n                    .entity(context.entity)\n                    .remove_by_id(context.component_id);\n                let name = world\n                    .components()\n                    .get_name(resource_component_id)","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ecs/src/resource.rs#L132-L168","documentation":"In this Bevy version, resources live on dedicated entities tracked by a `resource_entities` cache (keyed by `ComponentId`). The `IsResource` on_insert hook validates that cache; when the cached entity for that resource no longer exists in the world, the bookkeeping is corrupt (an entity was despawned behind the resource API's back) and the hook panics instead of silently resurrecting a dangling mapping.","triggerScenarios":"Despawning a resource's entity directly (e.g. `world.entity_mut(res_entity).despawn()` or a generic cleanup system sweeping entities) and then inserting/initializing the same resource again — the hook finds the stale cache entry pointing at a despawned entity and panics.","commonSituations":"Generic entity-cleanup or debug systems that despawn entities without excluding resource entities; experimentation code that despawns 'leftover' entities after removing a resource; hooks/state left stale after a partial world teardown in tests.","solutions":["Never despawn resource entities directly — remove resources with `world.remove_resource::<T>()` so the cache entry is cleared","If the cache is already stale, remove the resource through the resource API (clearing the mapping) before re-inserting or re-initializing it","Audit any despawn-all/cleanup systems to skip entities that carry the `IsResource` component"],"exampleFix":"// before\nworld.entity_mut(resource_entity).despawn(); // leaves stale resource_entities entry\nworld.init_resource::<Gold>(); // panics in on_insert hook\n\n// after\nworld.remove_resource::<Gold>(); // clears the cache entry properly\nworld.init_resource::<Gold>();","handlingStrategy":"validation","validationCode":"// Before generic despawn logic, exclude resource entities\nfn is_resource_entity(world: &World, entity: Entity) -> bool {\n    world.entity(entity).get::<IsResource>().is_some()\n}\n\nfor e in targets {\n    if !is_resource_entity(world, e) {\n        world.entity_mut(e).despawn();\n    }\n}","typeGuard":"fn is_resource_entity(world: &World, e: Entity) -> bool { world.entity(e).get::<IsResource>().is_some() }","tryCatchPattern":null,"preventionTips":["Use world.remove_resource::<T>() / init_resource for all resource lifecycle changes","Never call despawn on an entity you did not spawn yourself in ordinary gameplay code","In cleanup systems, filter out entities carrying IsResource before despawning"],"tags":["bevy","ecs","resources","entity-despawn","panic"],"backgroundTag":"stale-entity-reference","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}