bevyengine/bevy · error · DagCrossDependencyError
DAG has a cross-dependency between nodes {0:?} and {1:?}
Error message
DAG has a cross-dependency between nodes {0:?} and {1:?} What it means
`DagCrossDependencyError` is the low-level graph error stating that nodes `{0}` and `{1}` carry dependencies in both directions between the hierarchy and dependency graphs — concretely, a `before`/`after` edge between a node and a set that contains it. Bevy wraps it into `ScheduleBuildError::CrossDependency` during schedule initialization; the two node ids identify the conflicting pair.
Source
Thrown at crates/bevy_ecs/src/schedule/graph/dag.rs:719
fn default() -> Self {
Self(Default::default())
}
}
impl<K: Debug, V: Debug, S> Debug for DagGroups<K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("DagGroups").field(&self.0).finish()
}
}
/// Error indicating that the graph has redundant edges.
#[derive(Error, Debug)]
#[error("DAG has redundant edges: {0:?}")]
pub struct DagRedundancyError<N: GraphNodeId>(pub Vec<(N, N)>);
/// Error indicating that two graphs both have a dependency between the same nodes.
#[derive(Error, Debug)]
#[error("DAG has a cross-dependency between nodes {0:?} and {1:?}")]
pub struct DagCrossDependencyError<N>(pub N, pub N);
/// Error indicating that the graph has overlapping groups between two keys.
#[derive(Error, Debug)]
#[error("DAG has overlapping groups between keys {0:?} and {1:?}")]
pub struct DagOverlappingGroupError<K>(pub K, pub K);
#[cfg(test)]
mod tests {
use core::ops::DerefMut;
use crate::schedule::graph::{index, Dag, Direction, GraphNodeId, UnGraph};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct TestNode(u32);
impl GraphNodeId for TestNode {
type Adjacent = (TestNode, Direction);View on GitHub (pinned to 396ca72708)
Solutions
- Repoint the ordering at a sibling system or set that does not contain the constrained node
- Move the constrained node out of the set if it truly must bracket the set's execution
- Trace which plugins contribute the `in_set` and `before` edges — the conflict is often between edges from two different sources
Example fix
// before app.add_systems(Update, x.in_set(S).before(S)); // DagCrossDependencyError(x, S) // after app.add_systems(Update, x.in_set(S)); app.add_systems(Update, y.in_set(S).before(x)); // order inside the set instead
Defensive patterns
Strategy: try-catch
Validate before calling
// Guard at config time: never emit ordering vs a containing set
fn orderable(hierarchy: &SetHierarchy, node: SetId, target: SetId) -> bool {
!hierarchy.is_descendant_of(target, node)
} Try / catch
match schedule.initialize(&mut world) {
Err(ScheduleBuildError::CrossDependency(err @ DagCrossDependencyError(_, _))) => {
// err.0/err.1 name the node/set pair; repoint the .before/.after edge at a sibling
}
other => other.map(|_| ()),
} Prevention
- Order members against members, sets against sibling sets
- When integrating plugins, review whether your ordering target transitively contains your systems
- Keep the in_set lattice documented so 'ordering vs ancestor' mistakes are visible in review
When it happens
Trigger: The same condition as `CrossDependency`: a system or set ordered `.before`/`.after` a set it (transitively) belongs to. You encounter this raw type when matching on the inner error of `CrossDependency` or using the Dag API directly.
Common situations: Bracketing constraints ('run X after everything in set S' where X is in S); plugin A ordering against plugin B's set while contributing systems into it; transitive in_set chains making a local ordering global and self-referential.
Related errors
- DependencySort
- FlatDependencySort
- CrossDependency
- SetsHaveOrderButIntersect
- DAG has redundant edges: {0:?}
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/6ea4d8a460d6e282.
Report an issue: GitHub.