bevyengine/bevy · critical
Error when initializing schedule
Error message
Error when initializing schedule {:?}: {} What it means
Schedule::run initializes the schedule before executing it; if building the executable schedule fails (ordering cycles, self-loops, ambiguous SystemTypeSet ordering, other build errors), run() panics with this wrapper message. The text after the colon embeds the underlying ScheduleBuildError rendered against the graph and world, naming the offending nodes/edges. It fires on the first run of the schedule, typically the first frame.
Solutions
- Read the embedded detail after the colon - it identifies the exact nodes and constraint at fault; fix that underlying build error.
- Reproduce as a failing test: call app.update() once right after configuring systems so CI catches it before runtime.
- If you need the error instead of a panic, call schedule.initialize(&mut world) yourself and handle the Result before calling run().
Example fix
// before
schedule.run(&mut world); // panics on invalid graph
// after
if let Err(e) = schedule.initialize(&mut world) {
log::error!("bad schedule: {}", e.to_string(schedule.graph(), world));
return;
}
schedule.run(&mut world); Defensive patterns
Strategy: try-catch
Validate before calling
// Fail fast in a test instead of frame 1
#[test]
fn app_boots() {
let mut app = App::new();
app.add_plugins(DefaultPlugins);
app.update();
} Try / catch
if let Err(e) = schedule.initialize(&mut world) {
log::error!("schedule init failed: {}", e.to_string(schedule.graph(), world));
return; // skip running instead of letting run() panic
}
schedule.run(&mut world); Prevention
- Run one app.update() in CI for every schedule composition you ship.
- Centralize schedule configuration so constraints are auditable in one module.
- Treat any new ordering constraint as requiring a smoke test.
When it happens
Trigger: Any ScheduleBuildError surfacing through Schedule::run: a cycle or self-loop introduced by new ordering constraints, ordering against a duplicated system type, or graph inconsistencies added since the last successful run.
Common situations: App panics on frame 1 after adding a plugin or ordering constraint; systems/sets configured differently between test and app so a constraint only loops in one of them; large refactors of schedule configuration.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- BuilderSystem was not initialized before calling run_unsafe.
- executable schedule has not been built
- System input value was not found. Did you forget to…
- System set with key does not exist in the schedule
- System with key does not exist in the schedule
AI-assisted analysis of bevyengine/bevy@a62cce8c05 (2026-08-20).
Data as JSON: /api/errors/9e8ef7bae2ad9bd3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bevy_ecs/src/schedule/schedule.rs:595
self.executor_initialized = false;
self
}
/// Set whether the schedule applies deferred system buffers on final time or not. This is a catch-all
/// in case a system uses commands but was not explicitly ordered before an instance of
/// [`ApplyDeferred`]. By default this
/// setting is true, but may be disabled if needed.
pub fn set_apply_final_deferred(&mut self, apply_final_deferred: bool) -> &mut Self {
self.executor.set_apply_final_deferred(apply_final_deferred);
self
}
/// Runs all systems in this schedule on the `world`, using its current execution strategy.
pub fn run(&mut self, world: &mut World) {
#[cfg(feature = "trace")]
let _span = info_span!("schedule", name = ?self.label).entered();
world.check_change_ticks();
self.initialize(world).unwrap_or_else(|e| {
panic!(
"Error when initializing schedule {:?}: {}",
self.label,
e.to_string(self.graph(), world)
)
});
let error_handler = world.fallback_error_handler();
#[cfg(not(feature = "bevy_debug_stepping"))]
self.executor
.run(&mut self.executable, world, None, error_handler);
#[cfg(feature = "bevy_debug_stepping")]
{
let skip_systems = match world.get_resource_mut::<Stepping>() {
None => None,View on GitHub (pinned to a62cce8c05)