{"record":{"id":"f4c9f2f7e50f8e82","repo":"bevyengine/bevy","slug":"dependencysort","errorCode":"DependencySort","errorMessage":"Failed to topologically sort the dependency graph: {0}","messagePattern":"Failed to topologically sort the dependency graph: (.+?)","errorType":"error_code","errorClass":"ScheduleBuildError","httpStatus":null,"severity":"error","filePath":"crates/bevy_ecs/src/schedule/error.rs","lineNumber":27,"sourceCode":"        graph::{\n            DagCrossDependencyError, DagOverlappingGroupError, DagRedundancyError,\n            DiGraphToposortError, GraphNodeId,\n        },\n        AmbiguousSystemConflictsWarning, ConflictingSystems, NodeId, ScheduleGraph, SystemKey,\n        SystemSetKey, SystemTypeSetAmbiguityError,\n    },\n    world::World,\n};\n\n/// Category of errors encountered during [`Schedule::initialize`](crate::schedule::Schedule::initialize).\n#[non_exhaustive]\n#[derive(Error, Debug)]\npub enum ScheduleBuildError {\n    /// Tried to topologically sort the hierarchy of system sets.\n    #[error(\"Failed to topologically sort the hierarchy of system sets: {0}\")]\n    HierarchySort(DiGraphToposortError<NodeId>),\n    /// Tried to topologically sort the dependency graph.\n    #[error(\"Failed to topologically sort the dependency graph: {0}\")]\n    DependencySort(DiGraphToposortError<NodeId>),\n    /// Tried to topologically sort the flattened dependency graph.\n    #[error(\"Failed to topologically sort the flattened dependency graph: {0}\")]\n    FlatDependencySort(DiGraphToposortError<SystemKey>),\n    /// Tried to order a system (set) relative to a system set it belongs to.\n    #[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)]\n    CrossDependency(#[from] DagCrossDependencyError<NodeId>),\n    /// Tried to order system sets that share systems.\n    #[error(\"`{:?}` and `{:?}` have a `before`-`after` relationship (which may be transitive) but share systems.\", .0.0, .0.1)]\n    SetsHaveOrderButIntersect(#[from] DagOverlappingGroupError<SystemSetKey>),\n    /// Tried to order a system (set) relative to all instances of some system function.\n    #[error(transparent)]\n    SystemTypeSetAmbiguity(#[from] SystemTypeSetAmbiguityError),\n    /// Tried to run a schedule before all of its systems have been initialized.\n    #[error(\"Tried to run a schedule before all of its systems have been initialized.\")]\n    Uninitialized,\n    /// A warning that was elevated to an error.\n    #[error(transparent)]","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ecs/src/schedule/error.rs#L9-L45","documentation":"The dependency graph holds the `before`/`after` ordering constraints between systems and sets. `DependencySort` means that graph has a cycle: the ordering constraints form a loop, so no execution order satisfies them. This surfaces from `Schedule::initialize`, typically on the first run of the schedule.","triggerScenarios":"`a.before(b)` together with `b.before(a)` (or a longer transitive chain a→b→c→a); symmetric `.before`/`.after` introduced when merging plugins that each order against the other's systems; a set ordered before one of its own members indirectly.","commonSituations":"Two plugins mutually ordering their systems for 'safety'; incremental addition of ordering constraints over time that accidentally closes a loop; conditional ordering macros that expand to more edges than expected.","solutions":["Remove one edge in the reported cycle — the error identifies the nodes where topological sort stalled; map them back to the systems/sets","Audit plugin boundaries for symmetric before/after pairs and pick a single direction","Prefer `.in_set` plus one owner of ordering per relationship instead of ad-hoc pairwise `.before`/`.after`"],"exampleFix":"// before\napp.add_systems(Update, (a.before(b), b.before(a))); // cycle\n\n// after\napp.add_systems(Update, (a.before(b),));","handlingStrategy":"try-catch","validationCode":"// Before adding symmetric ordering, check the inverse edge in your own config model\n// or just attempt an early initialize in dev builds:\n#[cfg(test)]\nfn assert_builds(schedule: &mut Schedule, world: &mut World) {\n    schedule.initialize(world).expect(\"schedule must build\");\n}","typeGuard":null,"tryCatchPattern":"match schedule.initialize(&mut world) {\n    Err(ScheduleBuildError::DependencySort(err)) => {\n        // err identifies the NodeId where ordering constraints cycled; remove one .before/.after edge\n    }\n    other => other.map(|_| ()),\n}","preventionTips":["Prefer ordering sets once instead of pairwise system orderings scattered across plugins","Avoid mutual before/after when integrating two plugins — pick one direction","Add a test that builds the full app schedule graph on CI"],"tags":["bevy","ecs","schedule","ordering","cycle","topological-sort"],"backgroundTag":"dependency-cycle","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}