Skip to content

Using enable_state_scoped_entities will try to despawn entities twice, resulting in warnings #20866

@janhohenheim

Description

@janhohenheim

Bevy version and features

  • 0.17.0-dev

What you did

Since #19354, state scoping is implicit. The #[states(scoped_entities)] does nothing in the default case.

However, for a long time, the only way to enable state scoping was using enable_state_scoped_entities, so I expect many people to still have that in their code. In fact, I had that in my code while migrating to 0.17.0-dev.
But this will actually "enable" the state scope again, causing Bevy to try to despawn entities marked DespawnOnExitState twice, resulting in a very unhelpful warning.

Minimal repro:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<AppState>()
        // Evil!
        .enable_state_scoped_entities::<AppState>()
        .add_systems(Startup, spawn)
        .add_systems(Update, change_state)
        .run();
}

#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
#[states(scoped_entities)]
enum AppState {
    #[default]
    A,
    B,
}

fn spawn(mut commands: Commands) {
    commands.spawn(DespawnOnExitState(AppState::A));
}

fn change_state(mut next_state: ResMut<NextState<AppState>>) {
    next_state.set(AppState::B);
}

What went wrong

I get this warning:

2025-09-04T14:04:44.976611Z WARN bevy_ecs::err::handler: Encountered an error in command <bevy_ecs::system::commands::entity_command::despawn::{{closure}} as bevy_ecs::error::command_handling::CommandWithEntity<core::result::Result<(), bevy_ecs::world::error::EntityMutableFetchError>>>::with_entity::{{closure}}: The entity with ID 22v1 was despawned by src/demo/brain_atlas.rs:43:14

If you were attempting to apply a command to this entity,
and want to handle this error gracefully, consider using `EntityCommands::queue_handled` or `queue_silenced`.

Which

  • Doesn't use NameOrEntity, so good luck finding out which entity this is talking about and
  • tells you to use queue_handled or queue_silenced even though you as the user aren't actually calling any commands!

So this threw me for a loop, haha

Additional information

Note that #[states(scoped_entities)] does not cause duplicate enablings

Metadata

Metadata

Labels

A-StatesApp-level states machinesC-BugAn unexpected or incorrect behaviorS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions