Description
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.