This page documents Bevy's error codes for the current release. In case you are looking for the latest error codes from Bevy's main branch, you can find them in the repository.

B0002#

To keep Rust rules on references (either one mutable reference or any number of immutable references) on a resource, it is not possible to have more than one resource of a kind if one is mutable in the same system. This can happen between Res<T> and ResMut<T> for the same T, or between NonSend<T> and NonSendMut<T> for the same T.

Erroneous code example:

use bevy::prelude::*;

fn update_materials(
    mut material_updater: ResMut<Assets<StandardMaterial>>,
    current_materials: Res<Assets<StandardMaterial>>,
) {
    // ...
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_system(update_materials)
        .run();
}

This will panic, as it's not possible to have both a mutable and an immutable resource on State at the same time.

As a mutable resource already provide access to the current resource value, you can remove the immutable resource.

use bevy::prelude::*;

fn update_materials(
    mut material_updater: ResMut<Assets<StandardMaterial>>,
) {
    // ...
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_system(update_materials)
        .run();
}

B0001#

To keep Rust rules on references (either one mutable reference or any number of immutable references) on a component, it is not possible to have two queries on the same component when one request mutable access to it in the same system.

Erroneous code example:

use bevy::prelude::*;

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Enemy;

fn move_enemies_to_player(
    mut enemies: Query<&mut Transform, With<Enemy>>,
    player: Query<&Transform, With<Player>>,
) {
    // ...
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_system(move_enemies_to_player)
        .run();
}

This will panic, as it's not possible to have both a mutable and an immutable query on Transform at the same time.

You have two solutions:

Solution #1: use disjoint queries using Without

As a Player entity won't be an Enemy at the same time, those two queries will acutally never target the same entity. This can be encoded in the query filter with Without:

use bevy::prelude::*;

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Enemy;

fn move_enemies_to_player(
    mut enemies: Query<&mut Transform, With<Enemy>>,
    player: Query<&Transform, (With<Player>, Without<Enemy>)>,
) {
    // ...
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_system(move_enemies_to_player)
        .run();
}

Solution #2: use a ParamSet

A ParamSet will let you have conflicting queries as a parameter, but you will still be responsible of not using them at the same time in your system.

use bevy::prelude::*;

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Enemy;

fn move_enemies_to_player(
    mut transforms: ParamSet<(
        Query<&mut Transform, With<Enemy>>,
        Query<&Transform, With<Player>>,
    )>,
) {
    // ...
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_system(move_enemies_to_player)
        .run();
}