joaopamaral opened a new pull request, #61877: URL: https://github.com/apache/airflow/pull/61877
<!-- Thank you for contributing! Please provide above a brief description of the changes made in this pull request. Write a good git commit message following this guide: http://chris.beams.io/posts/git-commit/ Please make sure that your code changes are covered with tests. And in case of new features or big changes remember to adjust the documentation. Feel free to ping (in general) for the review if you do not see reaction for a few days (72 Hours is the minimum reaction time you can expect from volunteers) - we sometimes miss notifications. In case of an existing issue, reference it using one of the following: * closes: #ISSUE * related: #ISSUE --> hierarchical_alphabetical_sort was not included in SerializedTaskGroup, which caused an exception and broke the Grid view. This PR adds hierarchical_alphabetical_sort to SerializedTaskGroup to ensure it is properly serialized and prevent the Grid view from crashing. <img width="1474" height="804" alt="image" src="https://github.com/user-attachments/assets/d3a8d490-1e1b-4866-9d87-baab31c2fea3" /> ``` 2026-02-13 14:44:22.436 | INFO: 138.68.32.225:23230 - "GET /ui/structure/structure_data?dag_id=test_hierarchical_alphabetical_sort&external_dependencies=false&version_number=1 HTTP/1.1" 500 Internal Server Error 2026-02-13 14:44:22.440 | ERROR: Exception in ASGI application 2026-02-13 14:44:22.440 | + Exception Group Traceback (most recent call last): 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/_utils.py", line 79, in collapse_excgroups 2026-02-13 14:44:22.440 | | yield 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/base.py", line 183, in __call__ 2026-02-13 14:44:22.440 | | async with anyio.create_task_group() as task_group: 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 783, in __aexit__ 2026-02-13 14:44:22.440 | | raise BaseExceptionGroup( 2026-02-13 14:44:22.440 | | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) 2026-02-13 14:44:22.440 | +-+---------------- 1 ---------------- 2026-02-13 14:44:22.440 | | Traceback (most recent call last): 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 416, in run_asgi 2026-02-13 14:44:22.440 | | result = await app( # type: ignore[func-returns-value] 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/fastapi/applications.py", line 1082, in __call__ 2026-02-13 14:44:22.440 | | await super().__call__(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__ 2026-02-13 14:44:22.440 | | await self.middleware_stack(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__ 2026-02-13 14:44:22.440 | | raise exc 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__ 2026-02-13 14:44:22.440 | | await self.app(scope, receive, _send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 29, in __call__ 2026-02-13 14:44:22.440 | | await responder(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 130, in __call__ 2026-02-13 14:44:22.440 | | await super().__call__(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 46, in __call__ 2026-02-13 14:44:22.440 | | await self.app(scope, receive, self.send_with_compression) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 85, in __call__ 2026-02-13 14:44:22.440 | | await self.app(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/base.py", line 182, in __call__ 2026-02-13 14:44:22.440 | | with recv_stream, send_stream, collapse_excgroups(): 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/usr/python/lib/python3.12/contextlib.py", line 158, in __exit__ 2026-02-13 14:44:22.440 | | self.gen.throw(value) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/_utils.py", line 85, in collapse_excgroups 2026-02-13 14:44:22.440 | | raise exc 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/base.py", line 184, in __call__ 2026-02-13 14:44:22.440 | | response = await self.dispatch_func(request, call_next) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/airflow/api_fastapi/auth/middlewares/refresh_token.py", line 61, in dispatch 2026-02-13 14:44:22.440 | | response = await call_next(request) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/base.py", line 159, in call_next 2026-02-13 14:44:22.440 | | raise app_exc 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/base.py", line 144, in coro 2026-02-13 14:44:22.440 | | await self.app(scope, receive_or_disconnect, send_no_error) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 63, in __call__ 2026-02-13 14:44:22.440 | | await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app 2026-02-13 14:44:22.440 | | raise exc 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app 2026-02-13 14:44:22.440 | | await app(scope, receive, sender) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/routing.py", line 716, in __call__ 2026-02-13 14:44:22.440 | | await self.middleware_stack(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/routing.py", line 736, in app 2026-02-13 14:44:22.440 | | await route.handle(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/routing.py", line 290, in handle 2026-02-13 14:44:22.440 | | await self.app(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/routing.py", line 78, in app 2026-02-13 14:44:22.440 | | await wrap_app_handling_exceptions(app, request)(scope, receive, send) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app 2026-02-13 14:44:22.440 | | raise exc 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app 2026-02-13 14:44:22.440 | | await app(scope, receive, sender) 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/routing.py", line 75, in app 2026-02-13 14:44:22.440 | | response = await f(request) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/fastapi/routing.py", line 308, in app 2026-02-13 14:44:22.440 | | raw_response = await run_endpoint_function( 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/fastapi/routing.py", line 221, in run_endpoint_function 2026-02-13 14:44:22.440 | | return await run_in_threadpool(dependant.call, **values) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/starlette/concurrency.py", line 38, in run_in_threadpool 2026-02-13 14:44:22.440 | | return await anyio.to_thread.run_sync(func) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/anyio/to_thread.py", line 63, in run_sync 2026-02-13 14:44:22.440 | | return await get_async_backend().run_sync_in_worker_thread( 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2502, in run_sync_in_worker_thread 2026-02-13 14:44:22.440 | | return await future 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 986, in run 2026-02-13 14:44:22.440 | | result = context.run(func, *args) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/airflow/api_fastapi/core_api/routes/ui/structure.py", line 89, in structure_data 2026-02-13 14:44:22.440 | | nodes = [task_group_to_dict(child) for child in dag.task_group.topological_sort()] 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | File "/home/airflow/.local/lib/python3.12/site-packages/airflow/api_fastapi/core_api/services/ui/task_group.py", line 64, in task_group_to_dict 2026-02-13 14:44:22.440 | | for child in get_task_group_children_getter()(task_group) 2026-02-13 14:44:22.440 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-02-13 14:44:22.440 | | AttributeError: 'SerializedTaskGroup' object has no attribute 'hierarchical_alphabetical_sort' ``` ## After fix: <img width="1604" height="710" alt="image" src="https://github.com/user-attachments/assets/2fa69584-49a8-4ade-8093-25c8e56ba463" /> --- ##### Was generative AI tooling used to co-author this PR? <!-- If generative AI tooling has been used in the process of authoring this PR, please change below checkbox to `[X]` followed by the name of the tool, uncomment the "Generated-by". --> - [x] Claude <!-- Generated-by: [Tool Name] following [the guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions) --> --- * Read the **[Pull Request Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#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](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals)) is needed. * When adding dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x). * For significant user-facing changes create newsfragment: `{pr_number}.significant.rst` or `{issue_number}.significant.rst`, in [airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments). -- 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]
