|
| 1 | +# B0003 |
| 2 | + |
| 3 | +As commands are executed asynchronously, it is possible to issue a command on an entity that will no longer exist at the time of the command execution. |
| 4 | + |
| 5 | +Erroneous code example: |
| 6 | + |
| 7 | +```rust,should_panic |
| 8 | +use bevy::prelude::*; |
| 9 | +
|
| 10 | +fn main() { |
| 11 | + App::new() |
| 12 | + .add_plugins(DefaultPlugins) |
| 13 | + .add_startup_system(setup) |
| 14 | + .add_system(despawning) |
| 15 | + .add_system(use_entity.after(despawning)) |
| 16 | + .run(); |
| 17 | +} |
| 18 | +
|
| 19 | +struct MyEntity(Entity); |
| 20 | +
|
| 21 | +#[derive(Component)] |
| 22 | +struct Hello; |
| 23 | +
|
| 24 | +fn setup(mut commands: Commands) { |
| 25 | + let entity = commands.spawn().id(); |
| 26 | + commands.insert_resource(MyEntity(entity)); |
| 27 | +} |
| 28 | +
|
| 29 | +fn despawning(mut commands: Commands, entity: Option<Res<MyEntity>>) { |
| 30 | + if let Some(my_entity) = entity { |
| 31 | + commands.entity(my_entity.0).despawn(); |
| 32 | + commands.remove_resource::<MyEntity>(); |
| 33 | + } |
| 34 | +} |
| 35 | +
|
| 36 | +fn use_entity(mut commands: Commands, entity: Option<Res<MyEntity>>) { |
| 37 | + if let Some(my_entity) = entity { |
| 38 | + commands.entity(my_entity.0).insert(Hello); |
| 39 | + } |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +This will panic, as system `use_entity` is executed after system `despawning`. Without the system ordering specified here, the ordering would be random and this code would panic half the time. |
| 44 | + |
| 45 | +The default panic message is telling you the entity id (`0v0`) and the command that failed (adding a component `Hello`): |
| 46 | + |
| 47 | +```text |
| 48 | +thread 'main' panicked at 'error[B0003]: Could not add a component (of type `use_entity_after_despawn::Hello`) to entity 0v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:752:13 |
| 49 | +``` |
| 50 | + |
| 51 | +But you don't know which system tried to add a component, and which system despawned the entity. |
| 52 | + |
| 53 | +To get the system that created the command that panics, you can enable the `trace` feature of Bevy. This will add a panic handler that will print more informations: |
| 54 | + |
| 55 | +```text |
| 56 | + 0: bevy_ecs::schedule::stage::system_commands |
| 57 | + with name="use_entity_after_despawn::use_entity" |
| 58 | + at crates/bevy_ecs/src/schedule/stage.rs:880 |
| 59 | + 1: bevy_ecs::schedule::stage |
| 60 | + with name=Update |
| 61 | + at crates/bevy_ecs/src/schedule/mod.rs:337 |
| 62 | + 2: bevy_app::app::frame |
| 63 | + at crates/bevy_app/src/app.rs:113 |
| 64 | + 3: bevy_app::app::bevy_app |
| 65 | + at crates/bevy_app/src/app.rs:126 |
| 66 | +thread 'main' panicked at 'error[B0003]: Could not add a component (of type `use_entity_after_despawn::Hello`) to entity 0v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:752:13 |
| 67 | +``` |
| 68 | + |
| 69 | +From the first two lines, you now know that it panics while executing a command from the system `use_entity`. |
| 70 | + |
| 71 | +To get the system that created the despawn command, you can enable DEBUG logs for crate `bevy_ecs`, for example by setting the environment variable `RUST_LOG=bevy_ecs=debug`. This will log: |
| 72 | + |
| 73 | +```text |
| 74 | +DEBUG stage{name=Update}:system_commands{name="use_entity_after_despawn::despawning"}: bevy_ecs::world: Despawning entity 0v0 |
| 75 | +thread 'main' panicked at 'error[B0003]: Could not add a component (of type `use_entity_after_despawn::Hello`) to entity 0v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:752:13 |
| 76 | +``` |
| 77 | + |
| 78 | +From the first line, you know the entity `0v0` was despawned when executing a command from system `despawning`. In a real case, you could have many log lines, you will need to search for the exact entity from the panic message. |
| 79 | + |
| 80 | +Combining those two, you should get enough informations to understand why this panic is happening and how to fix it: |
| 81 | + |
| 82 | +```text |
| 83 | +DEBUG stage{name=Update}:system_commands{name="use_entity_after_despawn::despawning"}: bevy_ecs::world: Despawning entity 0v0 |
| 84 | + 0: bevy_ecs::schedule::stage::system_commands |
| 85 | + with name="use_entity_after_despawn::use_entity" |
| 86 | + at crates/bevy_ecs/src/schedule/stage.rs:880 |
| 87 | + 1: bevy_ecs::schedule::stage |
| 88 | + with name=Update |
| 89 | + at crates/bevy_ecs/src/schedule/mod.rs:337 |
| 90 | +thread 'main' panicked at 'error[B0003]: Could not add a component (of type `use_entity_after_despawn::Hello`) to entity 0v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:752:13 |
| 91 | +``` |
0 commit comments