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

  1. Identify the systems named by the error's SystemKeys and which of their set memberships contribute orderings; remove one membership or one ordering edge
  2. Pull the contested system out of one of the ordered sets, or stop ordering those two sets against each other
  3. 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

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


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