Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Yttrmin opened this issue Jul 25, 2024 · 0 comments · Fixed by #15398
Closed

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

Yttrmin opened this issue Jul 25, 2024 · 0 comments · Fixed by #15398
Labels
A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior

Comments

@Yttrmin
Copy link

Yttrmin commented Jul 25, 2024

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
@Yttrmin Yttrmin added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Jul 25, 2024
@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events and removed S-Needs-Triage This issue needs to be labelled labels Jul 25, 2024
@alice-i-cecile alice-i-cecile moved this to Active: engine observers and hooks in Alice's Work Planning Jul 25, 2024
github-merge-queue bot pushed a commit that referenced this issue Sep 24, 2024
…#15398)

# Objective

Fixes #14467

Observers and component lifecycle hooks are allowed to perform
operations that subsequently require `Entities` to be flushed, such as
reserving a new entity. If this occurs during an `on_remove` hook or an
`OnRemove` event trigger during an `EntityWorldMut::despawn`, a panic
will occur.

## Solution

Call `world.flush_entities()` after running `on_remove` hooks/observers
during `despawn`

## Testing

Added a new test that fails before the fix and succeeds afterward.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants