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
Add dag[id] subscript syntax to DAG and SerializedDAG for accessing any node (task or task group) by its fully-qualified ID.
Update TaskGroup.__getitem__ to raise TaskItemNotFound (instead of a raw KeyError) on a miss, so callers can catch either KeyError or TaskNotFound.
Introduce TaskItemNotFound(TaskNotFound, KeyError) as a new exception in airflow.sdk.exceptions (and re-export it from airflow.exceptions) — a KeyError subtype that also satisfies TaskNotFound, giving callers flexibility without breaking existing KeyError handlers.
Details
Component
Change
task-sdk/src/airflow/sdk/exceptions.py
Add TaskItemNotFound(TaskNotFound, KeyError)
airflow-core/src/airflow/exceptions.py
Re-export TaskItemNotFound; add fallback stub
task-sdk/src/airflow/sdk/definitions/dag.py
Add DAG.__getitem__: checks task_dict then task_group_dict, returns DAGNode
task-sdk/src/airflow/sdk/definitions/taskgroup.py
Update TaskGroup.__getitem__ to re-raise KeyError as TaskItemNotFound
Callers can catch it as KeyError (existing dict-style handlers), TaskNotFound (Airflow task-lookup handlers), or TaskItemNotFound (subscript-specific handlers).
The fallback stub in airflow.exceptions (active when airflow.sdk is not installed) mirrors the same __str__ override so str(exc) never includes the extra quotes that KeyError.__str__ adds.
Was generative AI tooling used to co-author this PR?
Yes (please specify the tool below)
Generated-by: Claude Sonnet 4.6 following the guidelines
Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
For significant user-facing changes create newsfragment: {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.
I'm considering renaming TaskItemNotFound to DagNodeNotFound (or simply NodeNotFound). The TaskItem name came from the method that raises it __getitem__ + the fact it wraps TaskNotFound.
I personally think {Dag}Node is better since it also covers task groups.
- introduce `TaskItemNotFound` (a `KeyError` subtype) to the SDK exceptions module.
- Enable `dag[task_id]` syntax, raising `TaskItemNotFound` on miss.
- Add `SerializedDAG.__getitem__` for consistency.
`dag[id]` now searches task_dict then task_group_dict, so both tasks and groups are reachable by their fully-qualified ID. SerializedDAG follows the same logic. Both chained access (`dag["group"]["task"]`) and qualified-id access (`dag["group.task"]`) are covered by new tests.
LGTM Implementation is correct as per my knowledge follows the same pattern as #64430 Exception hierarchy works as intended, dual access patterns both function properly.
LGTM Implementation is correct as per my knowledge follows the same pattern as #64430 Exception hierarchy works as intended, dual access patterns both function properly.
Thank you for taking a look! BTW it's possible to signal one's approval via the "Files changed" tab:
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
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.
related: #64430
Summary
dag[id]subscript syntax toDAGandSerializedDAGfor accessing any node (task or task group) by its fully-qualified ID.TaskGroup.__getitem__to raiseTaskItemNotFound(instead of a rawKeyError) on a miss, so callers can catch eitherKeyErrororTaskNotFound.TaskItemNotFound(TaskNotFound, KeyError)as a new exception inairflow.sdk.exceptions(and re-export it fromairflow.exceptions) — aKeyErrorsubtype that also satisfiesTaskNotFound, giving callers flexibility without breaking existingKeyErrorhandlers.Details
task-sdk/src/airflow/sdk/exceptions.pyTaskItemNotFound(TaskNotFound, KeyError)airflow-core/src/airflow/exceptions.pyTaskItemNotFound; add fallback stubtask-sdk/src/airflow/sdk/definitions/dag.pyDAG.__getitem__: checkstask_dictthentask_group_dict, returnsDAGNodetask-sdk/src/airflow/sdk/definitions/taskgroup.pyTaskGroup.__getitem__to re-raiseKeyErrorasTaskItemNotFoundairflow-core/src/airflow/serialization/definitions/dag.pySerializedDAG.__getitem__: same lookup logic, returnsSerializedOperator | SerializedTaskGroupUsage
Two access patterns for nested nodes
dag[id]supports two equivalent ways to reach a task inside a group:dag["section.my_task"]task_dict— O(1)dag["section"]["my_task"]dag["section"]returns theTaskGroup;tg["my_task"]resolves by labelBoth are tested. The flat lookup is marginally cheaper; the chained form is more readable when the group is already in scope.
TaskItemNotFoundexception hierarchyCallers can catch it as
KeyError(existing dict-style handlers),TaskNotFound(Airflow task-lookup handlers), orTaskItemNotFound(subscript-specific handlers).The fallback stub in
airflow.exceptions(active whenairflow.sdkis not installed) mirrors the same__str__override sostr(exc)never includes the extra quotes thatKeyError.__str__adds.Was generative AI tooling used to co-author this PR?
Generated-by: Claude Sonnet 4.6 following the guidelines
{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.