Skip to content

Fix dag list renders - #74426

Merged
bbovenzi merged 3 commits into
apache:mainfrom
astronomer:fix-dag-list-renders
Oct 13, 2026
Merged

bbovenzi merged 3 commits into
apache:mainfrom
astronomer:fix-dag-list-renders

Conversation

@bbovenzi

@bbovenzi bbovenzi commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Run States and Task States in #69619 introduced a bug when a user had many active dag runs where the dags list would be constantly remounting causing the page to render slowly but to constantly flicker and shift.

This fixes that. And also drops isFetching from DataTable. It was also causing excess rerenders of the dags list and I don't like the ProgressBar UI of it anyways.


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)
    Claude Sonnet 5

  • 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.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • 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.

@boring-cyborg boring-cyborg Bot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 7, 2026

@yuseok89 yuseok89 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up, and sorry for the extra work. I'll keep renderers module-level like this from now on.

Comment thread airflow-core/src/airflow/ui/src/pages/DagsList/DagsListColumns.tsx Outdated
Comment thread airflow-core/src/airflow/ui/src/pages/DagsList/DagsList.tsx
bbovenzi and others added 3 commits October 8, 2026 11:35
The rebase onto main kept a parameter the call site no longer passes, so
the options object arrived in the wrong position and destructuring the
third argument threw before the table could render. Reported in review
and by the Chromium, WebKit and Firefox E2E jobs.

Co-Authored-By: Claude <noreply@anthropic.com>
@bbovenzi
bbovenzi force-pushed the fix-dag-list-renders branch from 3372a49 to 67bcab0 Compare October 8, 2026 15:59

@pierrejeambrun pierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@bbovenzi
bbovenzi merged commit 9698823 into apache:main Oct 13, 2026
90 checks passed
@bbovenzi bbovenzi added this to the Airflow 3.4.0 milestone Oct 13, 2026
@bbovenzi
bbovenzi deleted the fix-dag-list-renders branch October 13, 2026 18:50
@bbovenzi bbovenzi added the backport-to-v3-4-test Backport to v3-4-test label Oct 14, 2026
seanghaeli added a commit to aws-mwaa/upstream-to-airflow that referenced this pull request Oct 14, 2026
main removed isFetching from DataTable in apache#74426 ("Drop isFetching from
tables"), which this branch's new Callbacks tab still passed, so tsc
failed after the merge with TS2322 on Callbacks.tsx:154.
vatsrahul1001 pushed a commit that referenced this pull request Oct 18, 2026
* Show deadline callback logs in a Callbacks tab on the Dag run view

Add a Callbacks tab to the Dag run view, shown only when the run has
deadline callbacks. It lists them (path, type, state, deadline alert,
deadline time, created at) from the existing deadlines endpoint, which
now also returns each deadline's callback id, type, state and path, and
links each one to its logs, rendered with the task instance log viewer.

The new GET /ui/dags/{dag_id}/dagRuns/{dag_run_id}/callbacks/{callback_id}/logs
reads a callback's logs from remote storage or the local log folder. The
triggerer now writes async callback output to triggerer_callbacks/... so
those logs can be read too.

* Show deadline and alert details above callback logs

Above a callback's logs, show the deadline alert and its rule, the
deadline time, how late the run was, and the callback type, state and
path, all from the existing deadlines and deadline alerts endpoints.
In the Callbacks tab, replace the Created At column with Missed by and
show callback types as Sync/Async.

* Show the callback's row from the Callbacks table above its logs

* Even out spacing above the callback log header

* Trim callback log UI and tests

* Explain why the callback log reader prefers stream() over read()

* Make the callback log reader generic

Replace read_callback_log with read_logs_at_paths, which reads logs not
tied to a TaskInstance from the given paths. The callback logs route now
builds the executor/triggerer callback paths itself.

* Type callback columns for react-table v9

* Give each triggerer callback its own log directory

With [logging] delete_local_logs=True, the S3, GCS, OSS, CloudWatch and
Elasticsearch handlers delete the uploaded log file's parent directory.
Triggerer callback logs sat directly in the per-Dag-run directory, so the
first callback to finish deleted the local logs of every other callback
still running in the same Dag run, and those were never uploaded.

* Expand callback logs in place in the Callbacks tab

Clicking Logs on a callback now opens its logs in a row under it,
instead of going to a separate page that repeated the callback's row.
That page also looked the callback up in the first page of the list,
so it lost the summary for callbacks past that page; it is removed.

DataTable gains optional getRowId and renderSubComponent props, using
TanStack's row expanding feature.

* Drop the isFetching prop from the Callbacks table

main removed isFetching from DataTable in #74426 ("Drop isFetching from
tables"), which this branch's new Callbacks tab still passed, so tsc
failed after the merge with TS2322 on Callbacks.tsx:154.

* Read callback logs only at the path for the callback's type

CloudWatch returns a lazy stream for any log stream name and reports a missing
stream as a log line, so trying executor_callbacks/ first always won and async
(triggerer) callback logs showed "No log stream found" instead of their log.

* Let remote log handlers read logs without a task instance

Widen RemoteLogIO.read and RemoteLogStreamIO.stream to accept ti=None, matching
upload, so callback logs no longer need a type: ignore. Elasticsearch, OpenSearch
and Cloud Logging key logs by task instance, so they now return no logs for
ti=None instead of raising AttributeError.

* Fix callback log tests on SQLite by passing a UUID to the callback id filter

The Uuid column's SQLite bind processor rejects a str, so set_callback_type
failed with "'str' object has no attribute 'hex'".
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-4-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
✅ v3-4-test PR Link

vatsrahul1001 pushed a commit that referenced this pull request Oct 18, 2026
* Fix dag card rerendering states

* Drop isFetching from tables

* UI: Fix Dags list error page from stale createColumns signature

The rebase onto main kept a parameter the call site no longer passes, so
the options object arrived in the wrong position and destructuring the
third argument threw before the table could render. Reported in review
and by the Chromium, WebKit and Firefox E2E jobs.



---------
(cherry picked from commit 9698823)

Co-authored-by: Brent Bovenzi <brent@astronomer.io>
Co-authored-by: Claude <noreply@anthropic.com>
vatsrahul1001 added a commit that referenced this pull request Oct 19, 2026
…in UI (#73580) (#74955)

* Show deadline callback logs in a Callbacks tab on the Dag run view

Add a Callbacks tab to the Dag run view, shown only when the run has
deadline callbacks. It lists them (path, type, state, deadline alert,
deadline time, created at) from the existing deadlines endpoint, which
now also returns each deadline's callback id, type, state and path, and
links each one to its logs, rendered with the task instance log viewer.

The new GET /ui/dags/{dag_id}/dagRuns/{dag_run_id}/callbacks/{callback_id}/logs
reads a callback's logs from remote storage or the local log folder. The
triggerer now writes async callback output to triggerer_callbacks/... so
those logs can be read too.

* Show deadline and alert details above callback logs

Above a callback's logs, show the deadline alert and its rule, the
deadline time, how late the run was, and the callback type, state and
path, all from the existing deadlines and deadline alerts endpoints.
In the Callbacks tab, replace the Created At column with Missed by and
show callback types as Sync/Async.

* Show the callback's row from the Callbacks table above its logs

* Even out spacing above the callback log header

* Trim callback log UI and tests

* Explain why the callback log reader prefers stream() over read()

* Make the callback log reader generic

Replace read_callback_log with read_logs_at_paths, which reads logs not
tied to a TaskInstance from the given paths. The callback logs route now
builds the executor/triggerer callback paths itself.

* Type callback columns for react-table v9

* Give each triggerer callback its own log directory

With [logging] delete_local_logs=True, the S3, GCS, OSS, CloudWatch and
Elasticsearch handlers delete the uploaded log file's parent directory.
Triggerer callback logs sat directly in the per-Dag-run directory, so the
first callback to finish deleted the local logs of every other callback
still running in the same Dag run, and those were never uploaded.

* Expand callback logs in place in the Callbacks tab

Clicking Logs on a callback now opens its logs in a row under it,
instead of going to a separate page that repeated the callback's row.
That page also looked the callback up in the first page of the list,
so it lost the summary for callbacks past that page; it is removed.

DataTable gains optional getRowId and renderSubComponent props, using
TanStack's row expanding feature.

* Drop the isFetching prop from the Callbacks table

main removed isFetching from DataTable in #74426 ("Drop isFetching from
tables"), which this branch's new Callbacks tab still passed, so tsc
failed after the merge with TS2322 on Callbacks.tsx:154.

* Read callback logs only at the path for the callback's type

CloudWatch returns a lazy stream for any log stream name and reports a missing
stream as a log line, so trying executor_callbacks/ first always won and async
(triggerer) callback logs showed "No log stream found" instead of their log.

* Let remote log handlers read logs without a task instance

Widen RemoteLogIO.read and RemoteLogStreamIO.stream to accept ti=None, matching
upload, so callback logs no longer need a type: ignore. Elasticsearch, OpenSearch
and Cloud Logging key logs by task instance, so they now return no logs for
ti=None instead of raising AttributeError.

* Fix callback log tests on SQLite by passing a UUID to the callback id filter

The Uuid column's SQLite bind processor rejects a str, so set_callback_type
failed with "'str' object has no attribute 'hex'".
(cherry picked from commit 71e74bc)

Co-authored-by: Sean Ghaeli <58916776+seanghaeli@users.noreply.github.com>
Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
vatsrahul1001 pushed a commit that referenced this pull request Oct 20, 2026
* Fix dag card rerendering states

* Drop isFetching from tables

* UI: Fix Dags list error page from stale createColumns signature

The rebase onto main kept a parameter the call site no longer passes, so
the options object arrived in the wrong position and destructuring the
third argument threw before the table could render. Reported in review
and by the Chromium, WebKit and Firefox E2E jobs.



---------
(cherry picked from commit 9698823)

Co-authored-by: Brent Bovenzi <brent@astronomer.io>
Co-authored-by: Claude <noreply@anthropic.com>
vatsrahul1001 added a commit that referenced this pull request Oct 20, 2026
…in UI (#73580) (#74955)

* Show deadline callback logs in a Callbacks tab on the Dag run view

Add a Callbacks tab to the Dag run view, shown only when the run has
deadline callbacks. It lists them (path, type, state, deadline alert,
deadline time, created at) from the existing deadlines endpoint, which
now also returns each deadline's callback id, type, state and path, and
links each one to its logs, rendered with the task instance log viewer.

The new GET /ui/dags/{dag_id}/dagRuns/{dag_run_id}/callbacks/{callback_id}/logs
reads a callback's logs from remote storage or the local log folder. The
triggerer now writes async callback output to triggerer_callbacks/... so
those logs can be read too.

* Show deadline and alert details above callback logs

Above a callback's logs, show the deadline alert and its rule, the
deadline time, how late the run was, and the callback type, state and
path, all from the existing deadlines and deadline alerts endpoints.
In the Callbacks tab, replace the Created At column with Missed by and
show callback types as Sync/Async.

* Show the callback's row from the Callbacks table above its logs

* Even out spacing above the callback log header

* Trim callback log UI and tests

* Explain why the callback log reader prefers stream() over read()

* Make the callback log reader generic

Replace read_callback_log with read_logs_at_paths, which reads logs not
tied to a TaskInstance from the given paths. The callback logs route now
builds the executor/triggerer callback paths itself.

* Type callback columns for react-table v9

* Give each triggerer callback its own log directory

With [logging] delete_local_logs=True, the S3, GCS, OSS, CloudWatch and
Elasticsearch handlers delete the uploaded log file's parent directory.
Triggerer callback logs sat directly in the per-Dag-run directory, so the
first callback to finish deleted the local logs of every other callback
still running in the same Dag run, and those were never uploaded.

* Expand callback logs in place in the Callbacks tab

Clicking Logs on a callback now opens its logs in a row under it,
instead of going to a separate page that repeated the callback's row.
That page also looked the callback up in the first page of the list,
so it lost the summary for callbacks past that page; it is removed.

DataTable gains optional getRowId and renderSubComponent props, using
TanStack's row expanding feature.

* Drop the isFetching prop from the Callbacks table

main removed isFetching from DataTable in #74426 ("Drop isFetching from
tables"), which this branch's new Callbacks tab still passed, so tsc
failed after the merge with TS2322 on Callbacks.tsx:154.

* Read callback logs only at the path for the callback's type

CloudWatch returns a lazy stream for any log stream name and reports a missing
stream as a log line, so trying executor_callbacks/ first always won and async
(triggerer) callback logs showed "No log stream found" instead of their log.

* Let remote log handlers read logs without a task instance

Widen RemoteLogIO.read and RemoteLogStreamIO.stream to accept ti=None, matching
upload, so callback logs no longer need a type: ignore. Elasticsearch, OpenSearch
and Cloud Logging key logs by task instance, so they now return no logs for
ti=None instead of raising AttributeError.

* Fix callback log tests on SQLite by passing a UUID to the callback id filter

The Uuid column's SQLite bind processor rejects a str, so set_callback_type
failed with "'str' object has no attribute 'hex'".
(cherry picked from commit 71e74bc)

Co-authored-by: Sean Ghaeli <58916776+seanghaeli@users.noreply.github.com>
Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
SameerMesiah97 pushed a commit to SameerMesiah97/airflow-oss-sm97 that referenced this pull request Oct 27, 2026
…e#73580)

* Show deadline callback logs in a Callbacks tab on the Dag run view

Add a Callbacks tab to the Dag run view, shown only when the run has
deadline callbacks. It lists them (path, type, state, deadline alert,
deadline time, created at) from the existing deadlines endpoint, which
now also returns each deadline's callback id, type, state and path, and
links each one to its logs, rendered with the task instance log viewer.

The new GET /ui/dags/{dag_id}/dagRuns/{dag_run_id}/callbacks/{callback_id}/logs
reads a callback's logs from remote storage or the local log folder. The
triggerer now writes async callback output to triggerer_callbacks/... so
those logs can be read too.

* Show deadline and alert details above callback logs

Above a callback's logs, show the deadline alert and its rule, the
deadline time, how late the run was, and the callback type, state and
path, all from the existing deadlines and deadline alerts endpoints.
In the Callbacks tab, replace the Created At column with Missed by and
show callback types as Sync/Async.

* Show the callback's row from the Callbacks table above its logs

* Even out spacing above the callback log header

* Trim callback log UI and tests

* Explain why the callback log reader prefers stream() over read()

* Make the callback log reader generic

Replace read_callback_log with read_logs_at_paths, which reads logs not
tied to a TaskInstance from the given paths. The callback logs route now
builds the executor/triggerer callback paths itself.

* Type callback columns for react-table v9

* Give each triggerer callback its own log directory

With [logging] delete_local_logs=True, the S3, GCS, OSS, CloudWatch and
Elasticsearch handlers delete the uploaded log file's parent directory.
Triggerer callback logs sat directly in the per-Dag-run directory, so the
first callback to finish deleted the local logs of every other callback
still running in the same Dag run, and those were never uploaded.

* Expand callback logs in place in the Callbacks tab

Clicking Logs on a callback now opens its logs in a row under it,
instead of going to a separate page that repeated the callback's row.
That page also looked the callback up in the first page of the list,
so it lost the summary for callbacks past that page; it is removed.

DataTable gains optional getRowId and renderSubComponent props, using
TanStack's row expanding feature.

* Drop the isFetching prop from the Callbacks table

main removed isFetching from DataTable in apache#74426 ("Drop isFetching from
tables"), which this branch's new Callbacks tab still passed, so tsc
failed after the merge with TS2322 on Callbacks.tsx:154.

* Read callback logs only at the path for the callback's type

CloudWatch returns a lazy stream for any log stream name and reports a missing
stream as a log line, so trying executor_callbacks/ first always won and async
(triggerer) callback logs showed "No log stream found" instead of their log.

* Let remote log handlers read logs without a task instance

Widen RemoteLogIO.read and RemoteLogStreamIO.stream to accept ti=None, matching
upload, so callback logs no longer need a type: ignore. Elasticsearch, OpenSearch
and Cloud Logging key logs by task instance, so they now return no logs for
ti=None instead of raising AttributeError.

* Fix callback log tests on SQLite by passing a UUID to the callback id filter

The Uuid column's SQLite bind processor rejects a str, so set_callback_type
failed with "'str' object has no attribute 'hex'".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UI Related to UI/UX. For Frontend Developers. backport-to-v3-4-test Backport to v3-4-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants