Skip to content

Panic when calling spawn_batch with an OnAdd observer which spawns entities #19348

@andrewhickman

Description

@andrewhickman

Bevy version

Tested on 0.16.0 and the main branch (673e70c)

What you did

The following code reproduces the issue:

use bevy::prelude::*;

#[derive(Component, Clone, Copy)]
struct Pawn;

fn main() -> AppExit {
    App::new()
        .add_observer(spawn_child)
        .add_systems(Update, spawn_batch)
        .run()
}

fn spawn_batch(mut commands: Commands) {
    commands.spawn_batch([Pawn; 2]);
}

fn spawn_child(_: Trigger<OnAdd, Pawn>, mut commands: Commands) {
    commands.spawn_empty();
}

What went wrong

I expected this code to spawn 4 entities - two Pawn entities from the spawn_batch call, and two empty entities spawned by the observer. Instead it panics


thread 'main' panicked at crates\bevy_ecs\src\entity\mod.rs:804:9:
flush() needs to be called before this operation is legal
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/17067e9ac6d7ecb70e50f92c1944e545188d2359/library\std\src\panicking.rs:697
   1: core::panicking::panic_fmt
             at /rustc/17067e9ac6d7ecb70e50f92c1944e545188d2359/library\core\src\panicking.rs:75
   2: bevy_ecs::entity::Entities::verify_flushed
             at .\crates\bevy_ecs\src\entity\mod.rs:804
   3: bevy_ecs::entity::Entities::alloc
             at .\crates\bevy_ecs\src\entity\mod.rs:812
   4: bevy_ecs::bundle::BundleSpawner::spawn<my_app::Pawn>
             at .\crates\bevy_ecs\src\bundle.rs:1792
   5: bevy_ecs::world::spawn_batch::impl$2::next<core::array::iter::IntoIter<my_app::Pawn,2> >
             at .\crates\bevy_ecs\src\world\spawn_batch.rs:76
   6: core::iter::traits::iterator::impl$0::next<bevy_ecs::world::spawn_batch::SpawnBatchIter<core::array::iter::IntoIter<my_app::Pawn,2> > >
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\iter\traits\iterator.rs:4049
   7: bevy_ecs::world::spawn_batch::impl$1::drop<core::array::iter::IntoIter<my_app::Pawn,2> >
             at .\crates\bevy_ecs\src\world\spawn_batch.rs:59
   8: core::ptr::drop_in_place<bevy_ecs::world::spawn_batch::SpawnBatchIter<core::array::iter::IntoIter<my_app::Pawn,2> > >
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:523
   9: bevy_ecs::system::commands::command::spawn_batch::closure$0<array$<my_app::Pawn,2> >
             at .\crates\bevy_ecs\src\system\commands\command.rs:77
  10: bevy_ecs::system::commands::command::impl$0::apply<bevy_ecs::system::commands::command::spawn_batch::closure_env$0<array$<my_app::Pawn,2> >,tuple$<> >
             at .\crates\bevy_ecs\src\system\commands\command.rs:62
  11: bevy_ecs::world::command_queue::impl$4::push::closure$0<bevy_ecs::system::commands::command::spawn_batch::closure_env$0<array$<my_app::Pawn,2> > >
             at .\crates\bevy_ecs\src\world\command_queue.rs:173
  12: core::ops::function::FnOnce::call_once<bevy_ecs::world::command_queue::impl$4::push::closure_env$0<bevy_ecs::system::commands::command::spawn_batch::closure_env$0<array$<my_app::Pawn,2> > >,tuple$<bevy_ptr::OwningPtr<bevy_ptr::Unaligned>,enum2$<core::optio
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
  13: bevy_ecs::world::command_queue::impl$4::apply_or_drop_queued::closure$0
             at .\crates\bevy_ecs\src\world\command_queue.rs:263
  14: core::panic::unwind_safe::impl$25::call_once<tuple$<>,bevy_ecs::world::command_queue::impl$4::apply_or_drop_queued::closure_env$0>
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\panic\unwind_safe.rs:272
  15: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::world::command_queue::impl$4::apply_or_drop_queued::closure_env$0>,tuple$<> >        
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:589
  16: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::simple::impl$0::run::closure_env$0>,tuple$<> >
  17: std::panicking::try
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:552
  18: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::world::command_queue::impl$4::apply_or_drop_queued::closure_env$0>,tuple$<> >
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:359
  19: bevy_ecs::world::command_queue::RawCommandQueue::apply_or_drop_queued
             at .\crates\bevy_ecs\src\world\command_queue.rs:268
  20: bevy_ecs::world::command_queue::CommandQueue::apply
             at .\crates\bevy_ecs\src\world\command_queue.rs:94
  21: bevy_ecs::world::command_queue::impl$6::apply
             at .\crates\bevy_ecs\src\world\command_queue.rs:326
  22: bevy_ecs::system::system_param::impl$22::apply<bevy_ecs::world::command_queue::CommandQueue>
             at .\crates\bevy_ecs\src\system\system_param.rs:1314
  23: bevy_ecs::system::system_param::impl$103::apply<bevy_ecs::system::system_param::Deferred<bevy_ecs::world::command_queue::CommandQueue>,ref$<bevy_ecs::entity::Entities> >
             at .\crates\bevy_ecs\src\system\system_param.rs:2101
  24: bevy_ecs::system::commands::_::impl$0::apply
             at .\crates\bevy_ecs\src\system\commands\mod.rs:155
  25: bevy_ecs::system::system_param::impl$101::apply<bevy_ecs::system::commands::Commands>
             at .\crates\bevy_ecs\src\system\system_param.rs:2101
  26: bevy_ecs::system::function_system::impl$7::apply_deferred<void (*)(bevy_ecs::system::commands::Commands),void (*)(bevy_ecs::system::commands::Commands)>
             at .\crates\bevy_ecs\src\system\function_system.rs:748
  27: bevy_ecs::system::schedule_system::impl$1::apply_deferred<bevy_ecs::system::function_system::FunctionSystem<void (*)(bevy_ecs::system::commands::Commands),void (*)(bevy_ecs::system::commands::Commands)> >
             at .\crates\bevy_ecs\src\system\schedule_system.rs:75
  28: bevy_ecs::schedule::executor::multi_threaded::apply_deferred::closure$0
             at .\crates\bevy_ecs\src\schedule\executor\multi_threaded.rs:800
  29: core::ops::function::FnOnce::call_once<bevy_ecs::schedule::executor::multi_threaded::apply_deferred::closure_env$0,tuple$<> >
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
  30: core::panic::unwind_safe::impl$25::call_once<tuple$<>,bevy_ecs::schedule::executor::multi_threaded::apply_deferred::closure_env$0>
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\panic\unwind_safe.rs:272
  31: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::multi_threaded::apply_deferred::closure_env$0>,tuple$<> >        
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:589
  32: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::simple::impl$0::run::closure_env$0>,tuple$<> >
  33: std::panicking::try
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:552
  34: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::multi_threaded::apply_deferred::closure_env$0>,tuple$<> >
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:359
  35: bevy_ecs::schedule::executor::multi_threaded::apply_deferred
             at .\crates\bevy_ecs\src\schedule\executor\multi_threaded.rs:799
  36: bevy_ecs::schedule::executor::multi_threaded::impl$2::run
             at .\crates\bevy_ecs\src\schedule\executor\multi_threaded.rs:302
  37: bevy_ecs::schedule::schedule::Schedule::run
             at .\crates\bevy_ecs\src\schedule\schedule.rs:448
  38: bevy_ecs::world::impl$4::try_run_schedule::closure$0<bevy_ecs::intern::Interned<dyn$<bevy_ecs::schedule::set::ScheduleLabel> > >
             at .\crates\bevy_ecs\src\world\mod.rs:3495
  39: bevy_ecs::world::World::try_schedule_scope<tuple$<>,bevy_ecs::intern::Interned<dyn$<bevy_ecs::schedule::set::ScheduleLabel> >,bevy_ecs::world::impl$4::try_run_schedule::closure_env$0<bevy_ecs::intern::Interned<dyn$<bevy_ecs::schedule::set::ScheduleLabel> >
             at .\crates\bevy_ecs\src\world\mod.rs:3428
  40: bevy_ecs::world::World::try_run_schedule<bevy_ecs::intern::Interned<dyn$<bevy_ecs::schedule::set::ScheduleLabel> > >
             at .\crates\bevy_ecs\src\world\mod.rs:3495
  41: bevy_app::main_schedule::impl$2::run_main::closure$1
             at .\crates\bevy_app\src\main_schedule.rs:296
  42: bevy_ecs::world::World::try_resource_scope<bevy_app::main_schedule::MainScheduleOrder,tuple$<>,bevy_app::main_schedule::impl$2::run_main::closure_env$1>
             at .\crates\bevy_ecs\src\world\mod.rs:2599
  43: bevy_ecs::world::World::resource_scope<bevy_app::main_schedule::MainScheduleOrder,tuple$<>,bevy_app::main_schedule::impl$2::run_main::closure_env$1>
             at .\crates\bevy_ecs\src\world\mod.rs:2562
  44: bevy_app::main_schedule::Main::run_main
             at .\crates\bevy_app\src\main_schedule.rs:294
  45: core::ops::function::FnMut::call_mut<void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool>),tuple$<ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool> > >
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:166
  46: core::ops::function::impls::impl$3::call_mut<tuple$<ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool> >,void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool>)>
             at C:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:294
  47: bevy_ecs::system::exclusive_function_system::impl$5::run::call_inner<tuple$<>,bevy_ecs::system::system_param::Local<bool>,ref_mut$<void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool>)> >
             at .\crates\bevy_ecs\src\system\exclusive_function_system.rs:259
  48: bevy_ecs::system::exclusive_function_system::impl$5::run<tuple$<>,void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool>),bevy_ecs::system::system_param::Local<bool> >
             at .\crates\bevy_ecs\src\system\exclusive_function_system.rs:262
  49: bevy_ecs::system::exclusive_function_system::impl$2::run_unsafe::closure$0<void (*)(bevy_ecs::system::system_param::Local<bool>),void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool>)>
             at .\crates\bevy_ecs\src\system\exclusive_function_system.rs:134
  50: bevy_ecs::world::World::last_change_tick_scope<tuple$<>,bevy_ecs::system::exclusive_function_system::impl$2::run_unsafe::closure_env$0<void (*)(bevy_ecs::system::system_param::Local<bool>),void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_
             at .\crates\bevy_ecs\src\world\mod.rs:2950
  51: bevy_ecs::system::exclusive_function_system::impl$2::run_unsafe<void (*)(bevy_ecs::system::system_param::Local<bool>),void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local<bool>)>
             at .\crates\bevy_ecs\src\system\exclusive_function_system.rs:126
  52: bevy_ecs::system::schedule_system::impl$1::run_unsafe<bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<void (*)(bevy_ecs::system::system_param::Local<bool>),void (*)(ref_mut$<bevy_ecs::world::World>,bevy_ecs::system::system_param::Local
             at .\crates\bevy_ecs\src\system\schedule_system.rs:69
  53: bevy_ecs::system::system::System::run_without_applying_deferred<bevy_ecs::system::schedule_system::InfallibleSystemWrapper<bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<void (*)(bevy_ecs::system::system_param::Local<bool>),void (*)(r
             at .\crates\bevy_ecs\src\system\system.rs:111
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Encountered a panic when applying buffers for system `my_app::spawn_batch`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorP-CrashA sudden unexpected crashS-Needs-InvestigationThis issue requires detective work to figure out what's going wrong

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions