Skip to content

Prevent React plugins from inheriting a prior bundle's component - #71943

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
astronomer:fix-react-plugin-stale-global
Aug 21, 2026
Merged

pierrejeambrun merged 1 commit into
apache:mainfrom
astronomer:fix-react-plugin-stale-global

Conversation

@pierrejeambrun

@pierrejeambrun pierrejeambrun commented Aug 21, 2026 •

Copy link
Copy Markdown
Member

A React plugin bundle exports its component by assigning to the shared globalThis.AirflowPlugin as a side effect of being imported. When a bundle is malformed or empty and never makes that assignment, the loader read whatever value a previously-loaded plugin had left on globalThis.AirflowPlugin — so one plugin silently rendered another plugin's component instead of failing. The typeof !== "function" guard didn't catch it because the stale value is a valid function.

This clears the shared global before each import, so a bundle that assigns nothing surfaces a clear error (and the error page) rather than inheriting a stale component. The resolved component is also cached under its plugin name only after validation, so a failed load never leaves a bad value behind.

Before

Plugin A

01-plugin-a ### Plugin B 02-plugin-b

After

Plugin A

01-plugin-a ### Plugin B 02-plugin-b

closes: #56169


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines

@boring-cyborg boring-cyborg Bot added the area:UI Related to UI/UX. For Frontend Developers. label Aug 21, 2026
@pierrejeambrun
pierrejeambrun force-pushed the fix-react-plugin-stale-global branch from bc7dcca to 5338e26 Compare August 21, 2026 12:36
@pierrejeambrun pierrejeambrun self-assigned this Aug 21, 2026
@pierrejeambrun pierrejeambrun added this to the Airflow 3.3.2 milestone Aug 21, 2026
@pierrejeambrun
pierrejeambrun marked this pull request as ready for review August 21, 2026 13:55
@pierrejeambrun
pierrejeambrun force-pushed the fix-react-plugin-stale-global branch from 5338e26 to b362853 Compare August 21, 2026 14:04
A React plugin bundle exports its component by assigning to the shared
globalThis.AirflowPlugin as a side effect of being imported. When a bundle is
malformed or empty and never makes that assignment, the loader read whatever
value a previously-loaded plugin had left there, so one plugin silently
rendered another plugin's component instead of failing. Clear the shared global
before each import so a bundle that assigns nothing surfaces a clear error
rather than inheriting a stale component.
@pierrejeambrun
pierrejeambrun force-pushed the fix-react-plugin-stale-global branch from b362853 to 09f7f8d Compare August 21, 2026 14:12
@bbovenzi

Copy link
Copy Markdown
Contributor

Good catch!

@pierrejeambrun
pierrejeambrun merged commit bdf3ee5 into apache:main Aug 21, 2026
89 checks passed
@pierrejeambrun
pierrejeambrun deleted the fix-react-plugin-stale-global branch August 21, 2026 15:35
@github-actions

Copy link
Copy Markdown
Contributor

Backport failed to create: v3-3-test. View the failure log Run details

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-3-test Commit Link

You can attempt to backport this manually by running:

cherry_picker bdf3ee5 v3-3-test

This should apply the commit to the v3-3-test branch and leave the commit in conflict state marking
the files that need manual conflict resolution.

After you have resolved the conflicts, you can continue the backport process by running:

cherry_picker --continue

If you don't have cherry-picker installed, see the installation guide.

pierrejeambrun added a commit that referenced this pull request Aug 27, 2026
) (#72136)

A React plugin bundle exports its component by assigning to the shared
globalThis.AirflowPlugin as a side effect of being imported. When a bundle is
malformed or empty and never makes that assignment, the loader read whatever
value a previously-loaded plugin had left there, so one plugin silently
rendered another plugin's component instead of failing. Clear the shared global
before each import so a bundle that assigns nothing surfaces a clear error
rather than inheriting a stale component.

(cherry picked from commit bdf3ee5)
vatsrahul1001 pushed a commit that referenced this pull request Sep 7, 2026
) (#72136)

A React plugin bundle exports its component by assigning to the shared
globalThis.AirflowPlugin as a side effect of being imported. When a bundle is
malformed or empty and never makes that assignment, the loader read whatever
value a previously-loaded plugin had left there, so one plugin silently
rendered another plugin's component instead of failing. Clear the shared global
before each import so a bundle that assigns nothing surfaces a clear error
rather than inheriting a stale component.

(cherry picked from commit bdf3ee5)
imrichardwu pushed a commit to imrichardwu/airflow that referenced this pull request Sep 11, 2026
…che#71943)

A React plugin bundle exports its component by assigning to the shared
globalThis.AirflowPlugin as a side effect of being imported. When a bundle is
malformed or empty and never makes that assignment, the loader read whatever
value a previously-loaded plugin had left there, so one plugin silently
rendered another plugin's component instead of failing. Clear the shared global
before each import so a bundle that assigns nothing surfaces a clear error
rather than inheriting a stale component.
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.

ReactPlugin: malformed bundles may inherit previous plugin components

2 participants