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

  1. Never despawn resource entities directly — remove resources with `world.remove_resource::<T>()` so the cache entry is cleared
  2. If the cache is already stale, remove the resource through the resource API (clearing the mapping) before re-inserting or re-initializing it
  3. 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

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


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/86cdd5daad910f89. Report an issue: GitHub.