This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun pushed a commit to branch v3-3-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-3-test by this push:
new bf6c14f1596 [v3-3-test] Fix Trigger Again showing empty config for the
selected run (#70248) (#70288)
bf6c14f1596 is described below
commit bf6c14f1596fe7ff3b1d8c5ac169df8890cf7e9e
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Jul 24 11:10:51 2026 +0200
[v3-3-test] Fix Trigger Again showing empty config for the selected run
(#70248) (#70288)
Re-triggering a Dag with the config of a selected run left the
configuration empty ("{}") whenever the Dag had no declared params or its
params had not loaded yet: the prefill only pushed the run's conf into the
param store when params were present, so the sync effect overwrote the form
back to the default empty config and the selected run's configuration was lost.
(cherry picked from commit 58160be43fcecc63d42527cc07c1465284fa7095)
Co-authored-by: Pierre Jeambrun <[email protected]>
---
.../components/TriggerDag/TriggerDAGForm.test.tsx | 46 +++++++++++++++++++++-
.../src/components/TriggerDag/TriggerDAGForm.tsx | 12 ++++--
2 files changed, 52 insertions(+), 6 deletions(-)
diff --git
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.test.tsx
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.test.tsx
index de15a092d9c..2181842f681 100644
---
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.test.tsx
+++
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.test.tsx
@@ -18,7 +18,7 @@
*/
import "@testing-library/jest-dom";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
-import { describe, expect, it, vi } from "vitest";
+import { beforeEach, describe, expect, it, vi } from "vitest";
import { Wrapper } from "src/utils/Wrapper";
@@ -47,8 +47,10 @@ vi.mock("react-i18next", () => ({
}),
}));
+const useDagParamsMock = vi.hoisted(() => vi.fn());
+
vi.mock("src/queries/useDagParams", () => ({
- useDagParams: () => dagParams,
+ useDagParams: useDagParamsMock,
}));
vi.mock("src/queries/useTogglePause", () => ({
@@ -83,6 +85,46 @@ vi.mock("../JsonEditor", () => ({
}));
describe("TriggerDAGForm", () => {
+ beforeEach(() => {
+ useDagParamsMock.mockReturnValue(dagParams);
+ });
+
+ it("propagates the selected run's conf to the JSON editor when the Dag has
no declared params", async () => {
+ useDagParamsMock.mockReturnValue({ paramsDict: {} });
+
+ render(
+ <TriggerDAGForm
+ dagDisplayName="No Params Dag"
+ dagId="example_no_params"
+ error={undefined}
+ hasSchedule={false}
+ isPartitioned={false}
+ isPaused={false}
+ isPending={false}
+ onSubmitTrigger={vi.fn()}
+ open
+ prefillConfig={{
+ conf: { message: "from selected run" },
+ logicalDate: undefined,
+ runId: "manual__test",
+ }}
+ />,
+ { wrapper: Wrapper },
+ );
+
+ fireEvent.click(screen.getByText("Advanced Options"));
+
+ await waitFor(() => {
+ const configJson = screen.getByLabelText("Configuration JSON");
+
+ if (!(configJson instanceof HTMLTextAreaElement)) {
+ throw new TypeError("Expected Configuration JSON to render as a
textarea");
+ }
+
+ expect(configJson.value).toContain('"from selected run"');
+ });
+ });
+
it("syncs Advanced Options JSON after Run Parameters edits in prefilled
re-trigger mode", async () => {
const { container } = render(
<TriggerDAGForm
diff --git
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
index ccd79c4fc25..185c3da46f9 100644
--- a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
@@ -107,10 +107,14 @@ const TriggerDAGForm = ({
note: "",
partitionKey: undefined,
});
- // Also update the param store to keep it in sync.
- // Wait until we have the initial params so section ordering stays
consistent.
- if (confString && Object.keys(initialParamsDict.paramsDict).length > 0) {
- if (Object.keys(initialParamDict).length === 0) {
+ // Also update the param store to keep it in sync. Seed the initial
params (for stable
+ // section ordering) only once they are available, but always push the
conf so a run's
+ // configuration propagates even for Dags with no declared params or
before params load.
+ if (confString) {
+ if (
+ Object.keys(initialParamsDict.paramsDict).length > 0 &&
+ Object.keys(initialParamDict).length === 0
+ ) {
setInitialParamDict(initialParamsDict.paramsDict);
}
setConf(confString);