Skip to content

UI: Fix XCom list crash when a value request fails - #74131

Merged
bbovenzi merged 2 commits into
apache:mainfrom
Jonghyun-An:fix/xcom-entry-query-errors
Oct 6, 2026
Merged

bbovenzi merged 2 commits into
apache:mainfrom
Jonghyun-An:fix/xcom-entry-query-errors

Conversation

@Jonghyun-An

@Jonghyun-An Jonghyun-An commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

An XCom entry can disappear between loading the list and fetching its value. The value request then returns 404, but XComEntry still tries to format undefined and throws Cannot read properties of undefined (reading 'match'). This replaces the entire list with an error page.

Handle the query error in the affected value cell so the other entries remain visible and can still be copied. The cell shows only the status code and alert-circle icon. Errors without an HTTP status show the translated Error label. Clicking it opens the full error in a shared ErrorModal based on DagImportErrorModal. Both XCom and Dag import errors use the same scrollable modal without custom height or width limits at the call site. Failed refetches also replace the stale value and its copy button with the error. Once a refetch succeeds, a later error stays closed until the user opens it.

I tested this change with Node.js 24.21.0 and pnpm 10.28.1 after rebasing on 2026-10-06. I ran corepack pnpm test --maxWorkers=4, which reported 1,609 passed across 182 test files with no unhandled errors. The default parallel run timed out in src/queryClient.test.ts. I reproduced the same timeout on main without this change. I ran corepack pnpm lint and corepack pnpm build. Both passed. Regular and manual prek checks passed on the six changed files.

I checked the production-compiled UI in Chromium with mocked HTTP responses for 404, 403, 500, structured 422 details and a network error. The failed and healthy rows stayed at 57 pixels. I checked Enter and Space activation, Escape and close-button dismissal, and focus returning to the error button. A long error remained scrollable and within both a 1440-pixel desktop viewport and a 390-pixel mobile viewport. These browser checks use local HTTP mocks and do not exercise an Airflow backend.

Screenshots

Original error that replaced the XCom list

Original XCom list replaced by a rendering error

Previous popover Updated inline status
Previous XCom error popover XCom status and alert icon with the remaining entries visible

Shared error modal

Full XCom error in the shared ErrorModal

Long error · Mobile view


Was generative AI tooling used to co-author this PR?
  • Yes — GPT-6.1-Sol, OpenAI Codex

Generated-by: GPT-6.1-Sol, OpenAI Codex following the guidelines

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

boring-cyborg Bot commented Oct 3, 2026

Copy link
Copy Markdown

Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide
Here are some useful points:

  • Pay attention to the quality of your code (ruff, mypy and type annotations). Our prek-hooks will help you with that.
  • In case of a new feature add useful documentation (in docstrings or in docs/ directory). Adding a new operator? Check this short guide Consider adding an example Dag that shows how users should use it.
  • Consider using Breeze environment for testing locally, it's a heavy docker but it ships with a working Airflow and a lot of integrations.
  • Be patient and persistent. It might take some time to get a review or get the final approval from Committers.
  • Please follow ASF Code of Conduct for all communication including (but not limited to) comments on Pull Requests, Mailing list and Slack.
  • Be sure to read the Airflow Coding style.
  • Always keep your Pull Requests rebased, otherwise your build might fail due to changes not related to your commits.
    Apache Airflow is a community-driven project and together we are making it better 🚀.
    In case of doubts contact the developers at:
    Mailing List: dev@airflow.apache.org
    Slack: https://s.apache.org/airflow-slack

A failed XCom value request takes down the entire list, hiding entries
whose values are still available. Those entries should remain readable
and copyable when an individual value cannot be fetched.
Keep only the status code and alert-circle icon in each failed XCom
cell. Use a shared ErrorModal for full XCom and Dag import errors.

Reset the details state when an error clears so a later failed refetch
does not reopen the modal automatically. Cover modal interactions,
structured errors, network failures, and recovery in the UI tests.
@Jonghyun-An
Jonghyun-An force-pushed the fix/xcom-entry-query-errors branch from 2b79ead to 08911f2 Compare October 6, 2026 05:29
@Jonghyun-An
Jonghyun-An requested a review from bbovenzi October 6, 2026 06:18
@bbovenzi bbovenzi added this to the Airflow 3.4.0 milestone Oct 6, 2026
@bbovenzi
bbovenzi merged commit b1e4ad0 into apache:main Oct 6, 2026
90 checks passed
@boring-cyborg

boring-cyborg Bot commented Oct 6, 2026

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

bbovenzi added a commit to astronomer/airflow that referenced this pull request Oct 14, 2026
Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on apache#74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.

Co-Authored-By: Claude <noreply@anthropic.com>
bbovenzi added a commit to astronomer/airflow that referenced this pull request Oct 19, 2026
Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on apache#74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.

Co-Authored-By: Claude <noreply@anthropic.com>
bbovenzi added a commit that referenced this pull request Oct 19, 2026
Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on #74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.

Co-authored-by: Claude <noreply@anthropic.com>
github-actions Bot pushed a commit to aws-mwaa/upstream-to-airflow that referenced this pull request Oct 19, 2026
…apache#74516)

Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on apache#74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.
(cherry picked from commit 7fbcfee)

Co-authored-by: Brent Bovenzi <brent@astronomer.io>
Co-authored-by: Claude <noreply@anthropic.com>
aws-airflow-bot pushed a commit to aws-mwaa/upstream-to-airflow that referenced this pull request Oct 19, 2026
…apache#74516)

Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on apache#74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.
(cherry picked from commit 7fbcfee)

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

Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on #74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.
(cherry picked from commit 7fbcfee)

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

Dag, Dag-run and task-instance headers had accumulated full-width banners that
stack on each other and repeat across pages. Draining and the pending review
indicator each had two separate implementations, so the same concept rendered
differently depending on which page you were on.

The approach follows review feedback on #74131: keep the short status inline
and put the detail behind the control that reports it. Each status now sits
where it can be read without crowding what it qualifies -- the deactivation
marker ahead of the breadcrumb, the backfill notice beside the Dag's name, the
retry reason among the task instance's own facts.

Reparse was previously hidden on a Dag that had failed to parse, which is the
state where it is most useful. A plugin that fails to load no longer replaces
the page with an error.
(cherry picked from commit 7fbcfee)

Co-authored-by: Brent Bovenzi <brent@astronomer.io>
Co-authored-by: Claude <noreply@anthropic.com>
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants