bevyengine/bevy · error · ScheduleBuildError

SetsHaveOrderButIntersect

SetsHaveOrderButIntersect

Error message

`{:?}` and `{:?}` have a `before`-`after` relationship (which may be transitive) but share systems.

What it means

`SetsHaveOrderButIntersect` fires when two system sets have a `before`/`after` relationship but share at least one system. The shared member would need to run both before and after itself relative to the sets' orderings, which is impossible, so schedule initialization fails with the two set keys named.

Source

Thrown at crates/bevy_ecs/src/schedule/error.rs:36

/// 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),
}

/// Category of warnings encountered during [`Schedule::initialize`](crate::schedule::Schedule::initialize).
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ScheduleBuildWarning {
    /// The hierarchy of system sets contains redundant edges.
    ///

View on GitHub (pinned to 396ca72708)

Solutions

  1. Remove the shared membership — keep each system in exactly one of the two ordered sets
  2. Or drop the ordering between the intersecting sets (order their non-shared members directly)
  3. If the overlap is intentional, model the shared systems as a third set and order the sets without intersection

Example fix

// before
app.configure_sets(Update, AiSet.before(PhysicsSet));
app.add_systems(Update, steering.in_set(AiSet).in_set(PhysicsSet)); // intersection

// after
app.add_systems(Update, steering.in_set(AiSet));
Defensive patterns

Strategy: try-catch

Validate before calling

// Maintain membership counts per set in your config; before ordering A vs B, assert:
assert!(shared_members(&set_a, &set_b).is_empty(), "ordered sets must not intersect");

Try / catch

match schedule.initialize(&mut world) {
    Err(ScheduleBuildError::SetsHaveOrderButIntersect(DagOverlappingGroupError(a, b))) => {
        // a and b share systems: drop the ordering or the shared membership
    }
    other => other.map(|_| ()),
}

Prevention

When it happens

Trigger: `.configure_sets(Update, A.before(B))` while some system is registered `.in_set(A).in_set(B)`; sets defined by disjoint concerns that accidentally share a member; base-set abstractions (e.g. a 'Everything' set) ordered against a specific set it contains members of.

Common situations: Cross-cutting sets (debug, networking) that collect systems also owned by phase sets, then get ordered against them; plugin composition where each plugin adds its systems to both a shared set and a local one that is later ordered; refactors introducing a second membership without checking ordering.

Related errors


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