Repository navigation
Fix short-circuit in a mapped task group not skipping later tasks - #74283
Merged
Merged
Conversation
1 task done
Inside a mapped task group, a short-circuit task that returned False only skipped the task right after it. Later tasks of the same map index still ran when their trigger rule accepts a skipped upstream (all_done, none_failed), although ignore_downstream_trigger_rules=True lists them in the skip decision. A task in a mapped task group now honours the skip decision of any SkipMixin task of the same group for its map index. The decisions are read with one query per scheduling pass, so tasks outside a mapped task group keep their current lookup.
…more paths Read the decisions with the same XCom query builder the rest of core uses, and drop a map index filter that could not change the result. Add a test that runs a short-circuit inside a task group expanded over an upstream task's output, where the later tasks are expanded only after the gate has run. Also check that a gate that failed or was removed after a clear is ignored, and that one pass evaluating two mapped task groups keeps their decisions apart.
A SkipMixin parent's decision counts once the parent has finished, in any state, for its direct downstream tasks, as it does outside a mapped task group and in Airflow 2. Only the tasks further down that this fix newly reaches require the writer to have succeeded, so a decision left behind by a cleared gate that never ran again does not skip them.
kaxil
force-pushed
the
fix-mapped-group-transitive-skip
branch
from
October 6, 2026 12:52
421594d to
bd50a26
Compare
vatsrahul1001
approved these changes
Oct 6, 2026
1 task done
vatsrahul1001
added a commit
that referenced
this pull request
Oct 7, 2026
The mapped-task-group skip-decision query added in #74283 reads XComModel.task_id/map_index/value directly in with_only_columns, which the check-xcom-model-columns prek hook forbids, turning the repo-wide static-check job red for every PR. Read them through xcom_entity(query) as the hook requires.
kaxil
pushed a commit
that referenced
this pull request
Oct 7, 2026
…g run (#74390) * Read XComModel columns through xcom_entity in NotPreviouslySkippedDep The mapped-task-group skip-decision query added in #74283 reads XComModel.task_id/map_index/value directly in with_only_columns, which the check-xcom-model-columns prek hook forbids, turning the repo-wide static-check job red for every PR. Read them through xcom_entity(query) as the hook requires. * Fix skip-decision tests for the xcom_v2 rename and add a cross-run guard The skip-decision query reads xcom_v2 after #74222, so capture_orm_selects needs that name (the read-once test was silently counting zero). Also add a regression test that a skip decision from one Dag run does not skip the same map index in another, which fails on the unscoped query. * Reformat with ruff format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes: #74175
related: #73959, #74188
Inside a mapped task group, a short-circuit task that returns False skips only the task right after it. Later tasks of the same map index still run if their trigger rule accepts a skipped upstream (
all_done,none_failed), even with the defaultignore_downstream_trigger_rules=True. The same chain outside a mapped task group skips them.The short-circuit already lists every downstream task in its skip decision. For an unmapped task the worker skips those task instances directly. For a mapped one it cannot, because a task inside a mapped task group is only expanded once its own dependencies are met, so the downstream task instances of that map index may not exist yet.
SkipMixinleaves the job toNotPreviouslySkippedDep, which only read the decision of direct upstream tasks. #73959 fixed the map index that lookup uses, so the first task is skipped again; this change covers the rest of the list.Airflow 2.11 has the same gap: its
SkipMixinalso leaves mapped task instances toNotPreviouslySkippedDep, and that dep also reads direct upstream tasks only. So this is not a regression from 2.x. It makes mapped task groups do whatignore_downstream_trigger_rules=Truedocuments, and what unmapped Dags already do in 2.x and 3.x.Design rationale
SkipMixintask. That task instance is skipped if the group's decision for its map index lists it underskipped. Unmapped Dags keep the existing direct-upstream lookup, with the same queries.XComModel.get_manyand kept on theDepContext, like the trigger-rule upstream counts. On main, the first task after an in-group short-circuit ran its own query for every map index.followedis still only read for direct downstream tasks. A branch operator lists only its direct children there. Reading it further down would skip every join.SkipMixintask, in every Dag, would then run its own XCom query on every scheduling pass. See the numbers below.Gotchas
ShortCircuitOperatordocs describe and as outside a mapped task group.ignore_downstream_trigger_rules=Falsekeeps them running: only the direct downstream is skipped and the rest follow their trigger rules.Benchmark
One
NotPreviouslySkippedDeppass over every schedulable task instance with a sharedDepContext, as the scheduler runs it, median of 3 runs in breeze on SQLite. "Mapped group 1000 x 10" is a short-circuit followed by a chain of 10all_donetasks in a task group expanded 1000 times.XCom queries per pass:
SkipMixintaskTime, with main and this PR swapped in turn in one container, two rounds:
SkipMixintaskIn a separate run of the same benchmark, #74188 took 0.64 s on the unmapped Dag where main took 0.029 s, and 7.39 s against 2.79 s with every gate True. In the short-circuited scenario main skips 500 task instances (only the first task of each short-circuited map index) and this PR skips all 5000, so most of its time there goes to the extra skip writes. These are SQLite numbers, where a query costs little. On Postgres or MySQL every query is also a network round trip.
Run
airflow standalone(scheduler,LocalExecutor, Postgres) with the Dags triggered through the REST API. Map index 1 has the gate returning False; map index 0 runs every task in these Dags.group.a[1]group.b[1]group.c[1]c,all_donenone_failedball_done,cnone_failedignore_downstream_trigger_rules=False,all_doneA task after the group succeeds in every Dag. A branch followed by a join inside a mapped task group skips only the branch not taken, and the join and the task after it succeed for both map indexes. An unmapped short-circuit chain is unchanged. On main,
airflow dags testof the first two Dags runsgroup.b[1]andgroup.c[1]. The expanded-over-output case also runs with real task execution intest_mappedoperator.py, and fails on main.Known issues
group.b[1]skips it again, because the short-circuit's decision still lists it. Outside a mapped task group a clearedbwould run. Clearing a direct child already behaves this way in both cases.{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.