Skip to content

Panic when a despawning Entity's observer spawns an Entity #14467

@Yttrmin

Description

@Yttrmin

Bevy version

0.14.0

What you did

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .add_systems(Startup, startup)
        .add_systems(Update, update)
        .run();
}

#[derive(Component)]
struct Marker;

fn startup(mut commands: Commands) {
    commands.spawn(Marker).observe(|_: Trigger<OnRemove, Marker>, mut commands: Commands| {
        commands.spawn_empty();
    });
}

fn update(
    query: Query<Entity, With<Marker>>,
    mut commands: Commands
) {
    for entity in &query {
        commands.entity(entity).despawn();
    }
}

What went wrong

What were you expecting?

  1. Entity with Marker component gets queued for despawning.
  2. Its observer runs and queues the spawning of a new entity.
  3. End result is the entity with Marker being despawned, and a new empty entity being spawned.
  4. App continues to run.

What actually happened?

thread 'main' panicked at F:\packages\cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\entity\mod.rs:582:9:
flush() needs to be called before this operation is legal
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `flush_panic_repro::update`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
error: process didn't exit successfully: `target\debug\flush_panic_repro.exe` (exit code: 101)

Additional information

#14300 runs into the same panic, but involves component hooks, MapEntities, and DynamicScene. I don't know enough about Bevy's internals to know if these are ultimately the same bug, or just coincidentally panic in the same spot.


If just the Marker component is removed without despawning its entity, the observer still runs (as expected) but there is no panic:

fn update(
    query: Query<Entity, With<Marker>>,
    mut commands: Commands
) {
    for entity in &query {
        commands.entity(entity).remove::<Marker>(); // Does NOT panic.
    }
}
// Rest of code is unchanged.

Here's what seems like the most relevant part of the panic backtrace:

2: bevy_ecs::entity::Entities::verify_flushed
   at F:\packages\cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\entity\mod.rs:582
3: bevy_ecs::entity::Entities::free
   at F:\packages\cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\entity\mod.rs:680
4: bevy_ecs::world::entity_ref::EntityWorldMut::despawn
   at F:\packages\cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\world\entity_ref.rs:1235
5: bevy_ecs::world::World::despawn
   at F:\packages\cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\world\mod.rs:1105
6: bevy_ecs::system::commands::despawn
   at F:\packages\cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\system\commands\mod.rs:1241

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behavior

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions