Skip to content

Crash when observing SceneInstanceReady trigger #19219

Open
@mbrea-c

Description

@mbrea-c

Bevy version

Bevy 0.16.0

[Optional] Relevant system information

SystemInfo { os: "Linux (NixOS 25.05)", kernel: "6.14.5", cpu: "AMD Ryzen 9 7940HS w/ Radeon 780M Graphics", core_count: "8", memory: "30.7 GiB" }
AdapterInfo { name: "AMD Radeon RX 7700S (RADV NAVI33)", vendor: 4098, device: 29824, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 25.0.5", backend: Vulkan }

What you did

The following code reproduces the issue:

use bevy::{prelude::*, scene::SceneInstanceReady};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands, mut scenes: ResMut<Assets<Scene>>) {
    let mut world = World::new();
    world.spawn(Name::new("Some entity"));
    let scene = scenes.add(Scene::new(world));

    for i in 0..5 {
        let parent = commands
            .spawn((Transform::default(), Visibility::default()))
            .id();

        commands
            .spawn((SceneRoot(scene.clone()), ChildOf(parent)))
            .observe(
                move |_: Trigger<SceneInstanceReady>, _: Res<SceneSpawner>| {
                    println!("Scene ready {i}");
                },
            );
    }
}

What went wrong

Running the program above results in a crash due to missing SceneSpawner resource:

Encountered an error in observer `bevy_repro::setup::{{closure}}`: Parameter `Res<SceneSpawner>` failed validation: Resource does not exist
   1: bevy_ecs::observer::runner::observer_system_runner
   2: hashbrown::raw::RawIterRange<T>::fold_impl
   3: bevy_ecs::observer::Observers::invoke
   4: bevy_ecs::observer::<impl bevy_ecs::world::World>::trigger_targets_with_caller
   5: core::ops::function::FnOnce::call_once
   6: bevy_ecs::world::command_queue::RawCommandQueue::apply_or_drop_queued
   7: bevy_ecs::world::entity_ref::EntityWorldMut::insert_with_caller
   8: bevy_ecs::world::entity_ref::EntityWorldMut::world_scope
   9: bevy_ecs::hierarchy::<impl bevy_ecs::world::entity_ref::EntityWorldMut>::add_child
  10: bevy_scene::scene_spawner::SceneSpawner::set_scene_instance_parent_sync
  11: bevy_ecs::world::World::resource_scope
  12: bevy_ecs::system::system::System::run
note: Some "noisy" backtrace lines have been filtered out. Run with `BEVY_BACKTRACE=full` for a verbose backtrace.

Encountered a panic in system `bevy_scene::scene_spawner::scene_spawner_system`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!

The expected behaviour is that the program doesn't crash (and the SceneSpawner resource should be available on the observer).

Additional information

This crash was a bit annoying to narrow down as it only happens if there are multiple scenes "queued" to be spawned at once, and they all have a parent (so that the set_scene_instance_parent_sync tries to call add_child).

The root cause here is that the add_child call will cause a command queue flush: since there are multiple scenes queued to be spawned in the same scene_spawner_system call, previous scenes' SceneInstanceReady observers will be triggered during the scene_spawner_system call, which causes the crash as the resource_scope::<SceneSpawnerSystem, _> call temporarily removes the SceneSpawner from the world.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorS-Needs-ReviewNeeds reviewer attention (from anyone!) to move forward

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions