You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Starting with Airflow 3.3.1, the Grid and Graph views return HTTP 500 for Dags whose TaskGroups have dependencies that form a cycle when each group is treated as a single unit, even though the task-level graph is acyclic. These Dags parse, schedule and run normally, and they rendered in the UI up to and including 3.3.0.
One proposed change (#73087) would reject these Dags at parse time. That is also a breaking change for existing Dags, this time with an import error. Before choosing a direction, I'd like community input on:
how to handle the regression,
whether these Dags should be allowed at all,
how any change should be rolled out and communicated.
UI: Fix Grid view for bidirectional TaskGroup dependencies #72822 tried to keep these Dags renderable in the UI by falling back to strongly-connected-component ordering. It was closed after review comments suggested that cyclic TaskGroup dependencies should be treated as invalid. Those comments noted that planned TaskGroup features (task loops, dynamic TaskGroups, "retry/clear this TaskGroup", "wait for TaskGroup completion") could have undefined behaviour on these Dags.
Reject cyclic TaskGroup dependencies during Dag parsing #73087 (open) proposes moving the failure to parse time with an import error that names the offending TaskGroup and the nodes involved in the cycle. Another user raised concerns there about doing this in a patch release without following the deprecation policy.
Affected Dag shapes
A task with no upstream task inside its own group counts as a root of that group, even when a task outside the group provides its only upstream. Group-level edges are built from those roots.
1. Sibling groups with dependencies in both directions:
2. Two tasks in one group bridged by a task outside it:
withDAG("tg_bridged", schedule=None):
withTaskGroup("g"):
a=EmptyOperator(task_id="a")
b=EmptyOperator(task_id="b")
ext=EmptyOperator(task_id="ext")
a>>ext>>b# g -> ext -> g
Both are acyclic at the task level. This pattern is common when TaskGroups are used for logical or visual grouping (for example one group per database schema) rather than as execution units. Users report hitting it when upgrading from 2.x to 3.3.1.
Emit a deprecation warning / Dag warning at parse time now, keep Grid/Graph working (e.g. with a fallback ordering), and hard-reject in a later minor or major release.
Hard-reject only from 3.4.0, and fix the 500 in 3.3.x separately.
What should 3.3.x users do in the meantime? Currently the only workaround is to restructure the Dag: remove the cycle or flatten the affected TaskGroups. Tasks keep running and stay reachable through the REST API.
Starting with Airflow 3.3.1, the Grid and Graph views return HTTP 500 for Dags whose TaskGroups have dependencies that form a cycle when each group is treated as a single unit, even though the task-level graph is acyclic. These Dags parse, schedule and run normally, and they rendered in the UI up to and including 3.3.0.
One proposed change (#73087) would reject these Dags at parse time. That is also a breaking change for existing Dags, this time with an import error. Before choosing a direction, I'd like community input on:
I'm affected by this on my own Dags as well.
How we got here
v3-3-testin [v3-3-test] Fix grid/graph view topological sort for group-level and cross-group dependencies (#69933) #70591, released in 3.3.1) fixed the group-level topological sort used by Grid/Graph (closes Tasks in the Grid view are not in topological order #65291). Before that change, the sort ignored group-to-group and cross-group edges and silently rendered an arbitrary order. It now takes those edges into account, so a pre-existing group-level cycle raisesValueError("A cyclic dependency occurred in dag: ..."), which surfaces as a 500 from the Grid and Graph endpoints.Affected Dag shapes
A task with no upstream task inside its own group counts as a root of that group, even when a task outside the group provides its only upstream. Group-level edges are built from those roots.
1. Sibling groups with dependencies in both directions:
2. Two tasks in one group bridged by a task outside it:
Both are acyclic at the task level. This pattern is common when TaskGroups are used for logical or visual grouping (for example one group per database schema) rather than as execution units. Users report hitting it when upgrading from 2.x to 3.3.1.
Impact by version
Open questions for the community
significantnewsfragment exists in Reject cyclic TaskGroup dependencies during Dag parsing #73087. Should there also be a known-issue note in the 3.3.1/3.3.2 release notes and/or an announcement on the dev/users mailing list?Related
Are you willing to submit PR?
Drafted-by: Claude Code (Opus 5.5); reviewed by @dheerajturaga before posting