bevyengine/bevy · error

Resource `{}` was inserted during a call to World::resource_

Error message

Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\nIn release builds, the value inserted will be overwritten at the end of the scope.

What it means

While World::resource_scope has R removed, inserting R again through the borrowed world (world.insert_resource::<R>(...) or commands/schedules inside the closure) violates the scope's contract. Debug builds panic immediately (or log an error via log::error! if already panicking, to avoid double-panic abort); release builds emit a warn! and silently overwrite your inserted value when the scope re-inserts the original at the end. The resource you receive as Mut<R> is the intended way to change it.

Source

Thrown at crates/bevy_ecs/src/world/mod.rs:2864

                // in debug mode, raise a panic if user code re-inserted a resource of this type within the scope.
                // resource insertion usually indicates a logic error in user code, which is useful to catch at dev time,
                // however it does not inherently lead to corrupted state, so we avoid introducing an unnecessary crash
                // for production builds.
                if entity_mut.contains_id(self.component_id) {
                    #[cfg(debug_assertions)]
                    {
                        // if we're already panicking, log an error instead of panicking, as double-panics result in an abort
                        #[cfg(feature = "std")]
                        if std::thread::panicking() {
                            log::error!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\
                                   In release builds, the value inserted will be overwritten at the end of the scope.",
                                   DebugName::type_name::<R>());
                            // return early to maintain consistent behavior with non-panicking calls in debug builds
                            return;
                        }

                        panic!("Resource `{}` was inserted during a call to World::resource_scope, which may result in unexpected behavior.\n\
                               In release builds, the value inserted will be overwritten at the end of the scope.",
                               DebugName::type_name::<R>());
                    }
                    #[cfg(not(debug_assertions))]
                    {
                        #[cold]
                        #[inline(never)]
                        fn warn_reinsert(resource_name: &str) {
                            warn!(
                                "Resource `{resource_name}` was inserted during a call to World::resource_scope: the inserted value will be overwritten.",
                            );
                        }

                        warn_reinsert(&DebugName::type_name::<R>());
                    }
                }

                move_as_ptr!(value);

View on GitHub (pinned to 396ca72708)

Solutions

  1. Mutate the resource in place through the Mut<R> the closure gives you (e.g. *state = State::new(...)) instead of inserting a new one.
  2. If you truly need to replace it, have the closure set a flag/value and perform world.insert_resource AFTER resource_scope returns.
  3. Audit any world.run_schedule / app.update / system run inside the closure for insert_resource of the scoped type and move it out of the scope.
  4. In release builds heed the warn! 'inserted value will be overwritten' — it marks the same bug without the panic.

Example fix

// before
world.resource_scope(|world, mut state: Mut<MyState>| {
    world.insert_resource(MyState::Restarting); // panic (debug) / silently overwritten (release)
});

// after
world.resource_scope(|world, mut state: Mut<MyState>| {
    *state = MyState::Restarting; // mutate in place
});
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Inside the resource_scope closure, calling world.insert_resource(R) / init_resource::<R>() for the SAME type R, or running a schedule/system that inserts R (e.g. world.run_schedule(SomeLabel) where a system in that schedule does res insertion). Resetting a state machine resource inside its own scope is the classic case.

Common situations: Resetting a State/Score/Timer resource by inserting a fresh value instead of mutating the Mut<R> handed to the closure; running another schedule inside the scope whose systems initialize the same resource; generic code that 'ensures resource exists' via insert_resource being reused inside a scope.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/61458ac6c8ca1fcf. Report an issue: GitHub.