bevyengine/bevy · error · ScheduleBuildError
FlatDependencySort
FlatDependencySort
Error message
Failed to topologically sort the flattened dependency graph: {0} What it means
After the hierarchy is applied, Bevy flattens set membership onto individual systems and topologically sorts that flattened graph. `FlatDependencySort` reports a cycle among `SystemKey`s — the individual edges were fine (or hidden) at set level, but once each system inherits its sets' orderings, the combined constraints on some system are contradictory.
Source
Thrown at crates/bevy_ecs/src/schedule/error.rs:30
},
AmbiguousSystemConflictsWarning, ConflictingSystems, NodeId, ScheduleGraph, SystemKey,
SystemSetKey, SystemTypeSetAmbiguityError,
},
world::World,
};
/// Category of errors encountered during [`Schedule::initialize`](crate::schedule::Schedule::initialize).
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ScheduleBuildError {
/// Tried to topologically sort the hierarchy of system sets.
#[error("Failed to topologically sort the hierarchy of system sets: {0}")]
HierarchySort(DiGraphToposortError<NodeId>),
/// Tried to topologically sort the dependency graph.
#[error("Failed to topologically sort the dependency graph: {0}")]
DependencySort(DiGraphToposortError<NodeId>),
/// Tried to topologically sort the flattened dependency graph.
#[error("Failed to topologically sort the flattened dependency graph: {0}")]
FlatDependencySort(DiGraphToposortError<SystemKey>),
/// Tried to order a system (set) relative to a system set it belongs to.
#[error("`{:?}` and `{:?}` have both `in_set` and `before`-`after` relationships (these might be transitive). This combination is unsolvable as a system cannot run before or after a set it belongs to.", .0.0, .0.1)]
CrossDependency(#[from] DagCrossDependencyError<NodeId>),
/// Tried to order system sets that share systems.
#[error("`{:?}` and `{:?}` have a `before`-`after` relationship (which may be transitive) but share systems.", .0.0, .0.1)]
SetsHaveOrderButIntersect(#[from] DagOverlappingGroupError<SystemSetKey>),
/// Tried to order a system (set) relative to all instances of some system function.
#[error(transparent)]
SystemTypeSetAmbiguity(#[from] SystemTypeSetAmbiguityError),
/// Tried to run a schedule before all of its systems have been initialized.
#[error("Tried to run a schedule before all of its systems have been initialized.")]
Uninitialized,
/// A warning that was elevated to an error.
#[error(transparent)]
Elevated(#[from] ScheduleBuildWarning),
}
View on GitHub (pinned to 396ca72708)
Solutions
- Identify the systems named by the error's SystemKeys and which of their set memberships contribute orderings; remove one membership or one ordering edge
- Pull the contested system out of one of the ordered sets, or stop ordering those two sets against each other
- Collapse duplicated organizational sets into one so each system has a single ordering source
Example fix
// before app.configure_sets(Update, (Combat.after(Physics),)); app.add_systems(Update, sync.in_set(Physics).in_set(Combat)); // flattened cycle // after app.add_systems(Update, sync.in_set(Physics));
Defensive patterns
Strategy: try-catch
Validate before calling
// Early-build the schedule during development to surface flattened cycles before runtime let _ = schedule.initialize(&mut world); // inspect the Result in dev/test builds
Try / catch
match schedule.initialize(&mut world) {
Err(ScheduleBuildError::FlatDependencySort(err)) => {
// SystemKey-level cycle: log err, then audit shared memberships of the involved systems
}
other => other.map(|_| ()),
} Prevention
- Keep each system in one ordering-relevant set; use additional sets only for unordered grouping
- Document which sets are ordered relative to which
- Integration-test plugin combinations, since flattened cycles often appear only when plugins combine
When it happens
Trigger: A system belonging to two ordered sets inheriting contradictory directions; ordering constraints between sets that expand into a loop over shared member systems; `.before`/`.after` on a set combined with member systems' own constraints closing a transitive cycle only visible after flattening.
Common situations: Systems placed in multiple organizational sets (feature set + phase set) where the sets are also ordered against each other; plugin sets that overlap and are ordered; refactors that move a system into a set that participates in an opposing chain.
Related errors
- DependencySort
- HierarchySort
- CrossDependency
- SetsHaveOrderButIntersect
- DAG has a cross-dependency between nodes {0:?} and {1:?}
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/03bdda5134480654.
Report an issue: GitHub.