Aditya-XR opened a new pull request, #76085:
URL: https://github.com/apache/airflow/pull/76085

   Calling a `@task_group` function three or more times inside another 
`TaskGroup` stops the Dag from importing. Two calls work, and three calls work 
at the top level of a Dag.
   
   ```python
   from airflow.sdk import DAG, TaskGroup, task, task_group
   
   
   @task
   def work():
       pass
   
   
   @task_group
   def inner():
       work()
   
   
   with DAG("nested_task_group_repro", schedule=None):
       with TaskGroup("outer"):
           for _ in range(3):
               inner()
   ```
   
   ```
   airflow.sdk.exceptions.DuplicateTaskIdFound: Task Group id 'outer.inner__1' 
has already been added to the Dag
   ```
   
   This reproduces on 3.3.2 and on `main`. In a Dag file it shows up as an 
import error.
   
   `_check_for_group_id_collisions` detects the collision with the prefixed id 
(`outer.inner`), but looked for taken suffixes with a regex built from the bare 
id (`^inner__\d+$`). `used_group_ids` stores prefixed ids, so `outer.inner__1` 
never matched and the third call got `__1` again. The lookup now uses the 
prefixed id, as `get_unique_task_id` already does for tasks. It is escaped 
because the dots in a prefix would otherwise match any character.
   
   **Behaviour note:** the same mismatch also skewed numbering without 
crashing. If `ingest` is called three times at the top level and twice inside 
`eu`, the second nested group was `eu.ingest__3` and is now `eu.ingest__1`, so 
task ids in a Dag with that exact shape change.
   
   **Testing**
   
   - New parametrized `test_repeated_task_group_in_parent_gets_next_suffix`: 
all 4 cases fail without the fix and pass with it.
   - `test_taskgroup.py`, `decorators/test_task_group.py` and 
`_internal/test_loop.py` in task-sdk: 126 passed.
   - `test_task_group.py` and `test_dag_serialization.py` in airflow-core: 289 
passed.
   - All of `task-sdk/tests`: 4241 passed, 7 failed. The same 7 fail without 
this change: 3 need `deltalake`, which isn't installed here, plus 3 
`test_param` format cases and `test_hook_values`.
   - A Dag with two groups that each call a `@task_group` three times, loaded 
through `DagBag`: import error without the fix; with it the Dag parses and its 
serialization round trip matches.
   - `prek` pre-commit and manual stages pass, including mypy for task-sdk.
   
   Tests ran with `uv run`, not `breeze`, because I have no Docker available. 
The `breeze testing` suites and `breeze build-docs` were not run.
   
   related: #41596
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 5.5)
   
   Generated-by: Claude Code (Opus 5.5) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to