bevyengine/bevy · error
Resource entity {} of {} has been despawned, when it's not s
Error message
Resource entity {} of {} has been despawned, when it's not supposed to be. What it means
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.
Source
Thrown at crates/bevy_ecs/src/resource.rs:150
/// The [`ComponentId`] of the resource component (the _actual_ resource value component, not the [`IsResource`] component).
pub fn resource_component_id(&self) -> ComponentId {
self.0
}
pub(crate) fn on_insert(mut world: DeferredWorld, context: HookContext) {
let resource_component_id = world
.entity(context.entity)
.get::<Self>()
.unwrap()
.resource_component_id();
if let Some(original_entity) = world.resource_entities.get(resource_component_id) {
if !world.entities().contains(original_entity) {
let name = world
.components()
.get_name(resource_component_id)
.expect("resource is registered");
panic!(
"Resource entity {} of {} has been despawned, when it's not supposed to be.",
original_entity, name
);
}
if original_entity != context.entity {
// the resource already exists and the new one should be removed
world
.commands()
.entity(context.entity)
.remove_by_id(resource_component_id);
world
.commands()
.entity(context.entity)
.remove_by_id(context.component_id);
let name = world
.components()
.get_name(resource_component_id)View on GitHub (pinned to 396ca72708)
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
Example fix
// before world.entity_mut(resource_entity).despawn(); // leaves stale resource_entities entry world.init_resource::<Gold>(); // panics in on_insert hook // after world.remove_resource::<Gold>(); // clears the cache entry properly world.init_resource::<Gold>();
Defensive patterns
Strategy: validation
Validate before calling
// Before generic despawn logic, exclude resource entities
fn is_resource_entity(world: &World, entity: Entity) -> bool {
world.entity(entity).get::<IsResource>().is_some()
}
for e in targets {
if !is_resource_entity(world, e) {
world.entity_mut(e).despawn();
}
} Type guard
fn is_resource_entity(world: &World, e: Entity) -> bool { world.entity(e).get::<IsResource>().is_some() } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cannot call `ReflectComponent::reflect_mut` on component {na
- Cannot call `ReflectComponent::reflect_unchecked_mut` on com
- System with key {:?} does not exist in the schedule
- System set with key {:?} does not exist in the schedule
- Error when initializing schedule {:?}: {}
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/86cdd5daad910f89.
Report an issue: GitHub.