{"record":{"id":"101ff2b98e29f885","repo":"bevyengine/bevy","slug":"cycles-detected-0","errorCode":null,"errorMessage":"cycles detected: {0:?}","messagePattern":"cycles detected: (.+?)","errorType":"exception","errorClass":"DiGraphToposortError","httpStatus":null,"severity":"error","filePath":"crates/bevy_ecs/src/schedule/graph/graph_map.rs","lineNumber":526,"sourceCode":"        }\n\n        cycles\n    }\n\n    /// Iterate over all *Strongly Connected Components* in this graph.\n    pub(crate) fn iter_sccs(&self) -> impl Iterator<Item = SmallVec<[N; 4]>> + '_ {\n        super::tarjan_scc::new_tarjan_scc(self)\n    }\n}\n\n/// Error returned when topologically sorting a directed graph fails.\n#[derive(Error, Debug)]\npub enum DiGraphToposortError<N: GraphNodeId> {\n    /// A self-loop was detected.\n    #[error(\"self-loop detected at node `{0:?}`\")]\n    Loop(N),\n    /// Cycles were detected.\n    #[error(\"cycles detected: {0:?}\")]\n    Cycle(Vec<Vec<N>>),\n}\n\n/// Edge direction.\n#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]\n#[repr(u8)]\npub enum Direction {\n    /// An `Outgoing` edge is an outward edge *from* the current node.\n    Outgoing = 0,\n    /// An `Incoming` edge is an inbound edge *to* the current node.\n    Incoming = 1,\n}\n\nimpl Direction {\n    /// Return the opposite `Direction`.\n    #[inline]\n    pub fn opposite(self) -> Self {\n        match self {","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ecs/src/schedule/graph/graph_map.rs#L508-L544","documentation":"The schedule dependency graph is topologically sorted before execution; this variant (DiGraphToposortError::Cycle) reports one or more cycles of length >= 2: two or more systems/sets order against each other in a loop (A before B while B before A), so no valid run order exists. Each inner Vec in the payload is one cycle, listed by node ids.","triggerScenarios":"Conflicting constraints such as a.before(b) combined with b.after(a); mixing tuple .chain() (which implies a->b) with an explicit constraint in the opposite direction; two sets configured to run before each other; a system ordered against a set whose members are ordered back against the first system.","commonSituations":"Ordering constraints split across multiple plugins that each contribute half of a loop; renaming or moving systems so an old constraint now closes a cycle; adding .chain() to an existing tuple that already had manual .before()/.after() calls.","solutions":["Trigger the failure deterministically (schedule.initialize(&mut world) or one app.update() in a test) and print the error with e.to_string(schedule.graph(), world) - it lists each cycle and its nodes.","Delete one edge of the reported cycle - usually the most recently added constraint or the one duplicated by .chain().","Centralize ordering in configure_sets so the relative order between feature sets is declared in exactly one place."],"exampleFix":"// before\napp.add_systems(Update, (a, b).chain()); // implies a -> b\napp.add_systems(Update, a.after(b)); // implies b -> a: cycle\n\n// after\napp.add_systems(Update, (a, b).chain());","handlingStrategy":"validation","validationCode":"// Catch ordering cycles at build time, not mid-game\n#[test]\nfn schedule_has_no_cycles() {\n    let mut app = App::new();\n    // add all plugins/systems/sets the app composes\n    app.update();\n}","typeGuard":null,"tryCatchPattern":"match schedule.initialize(&mut world) {\n    Ok(()) => schedule.run(&mut world),\n    Err(e) => log::error!(\"cycles: {}\", e.to_string(schedule.graph(), world)),\n}","preventionTips":["Declare cross-plugin ordering once at the set level (feature sets before/after each other).","When adding .chain() to existing tuples, audit the manual .before()/.after() calls you wrote for those systems.","Add a startup smoke test per schedule configuration."],"tags":["bevy","ecs","schedule","system-ordering","dependency-cycle","topological-sort"],"backgroundTag":"circular-dependency-detected","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}