This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 0224303bc68 Fix backfill run_on_latest_version defaulting to False 
instead of True (#59304)
0224303bc68 is described below

commit 0224303bc68d30573d87cc141c1d246806db906f
Author: Ephraim Anierobi <[email protected]>
AuthorDate: Thu Dec 11 17:40:08 2025 +0100

    Fix backfill run_on_latest_version defaulting to False instead of True 
(#59304)
    
    The run_on_latest_version parameter for backfills was incorrectly
    defaulting to False in the CLI, API, and UI. This fix ensures that
    backfills default to using the latest bundle version, which is the
    intended behavior.
    
    Changes:
    - Set ARG_BACKFILL_RUN_ON_LATEST_VERSION default to True in CLI
    - Add run_on_latest_version field with default=True to BackfillPostBody API 
model
    - Update API route to use request body value instead of hardcoded True
    - Update UI form to include run_on_latest_version: true in defaultValues
    - Update tests to reflect the new default behavior
    - Refactor RunBackfillForm to reduce line count below 250 to comply with 
max-lines linting rule
---
 .../api_fastapi/core_api/datamodels/backfills.py   |  1 +
 .../core_api/openapi/v2-rest-api-generated.yaml    |  4 +++
 .../core_api/routes/public/backfills.py            |  1 +
 airflow-core/src/airflow/cli/cli_config.py         |  5 +--
 .../airflow/ui/openapi-gen/requests/schemas.gen.ts |  5 +++
 .../airflow/ui/openapi-gen/requests/types.gen.ts   |  1 +
 .../src/components/DagActions/RunBackfillForm.tsx  | 42 +++++++++-------------
 .../unit/cli/commands/test_backfill_command.py     |  6 ++--
 .../src/airflowctl/api/datamodels/generated.py     |  1 +
 9 files changed, 36 insertions(+), 30 deletions(-)

diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py 
b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py
index 94a2c032a39..869c4ba38a8 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py
@@ -36,6 +36,7 @@ class BackfillPostBody(StrictBaseModel):
     dag_run_conf: dict = {}
     reprocess_behavior: ReprocessBehavior = ReprocessBehavior.NONE
     max_active_runs: int = 10
+    run_on_latest_version: bool = True
 
 
 class BackfillResponse(BaseModel):
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
 
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
index fb07b23aabc..5bcc026a26e 100644
--- 
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
+++ 
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
@@ -8965,6 +8965,10 @@ components:
           type: integer
           title: Max Active Runs
           default: 10
+        run_on_latest_version:
+          type: boolean
+          title: Run On Latest Version
+          default: true
       additionalProperties: false
       type: object
       required:
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py 
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py
index 3684776784a..adbac360247 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py
@@ -242,6 +242,7 @@ def create_backfill(
             dag_run_conf=backfill_request.dag_run_conf,
             triggering_user_name=user.get_name(),
             reprocess_behavior=backfill_request.reprocess_behavior,
+            run_on_latest_version=backfill_request.run_on_latest_version,
         )
         return BackfillResponse.model_validate(backfill_obj)
 
diff --git a/airflow-core/src/airflow/cli/cli_config.py 
b/airflow-core/src/airflow/cli/cli_config.py
index 0a02680a136..80e00a38423 100644
--- a/airflow-core/src/airflow/cli/cli_config.py
+++ b/airflow-core/src/airflow/cli/cli_config.py
@@ -346,10 +346,11 @@ ARG_BACKFILL_REPROCESS_BEHAVIOR = Arg(
 ARG_BACKFILL_RUN_ON_LATEST_VERSION = Arg(
     ("--run-on-latest-version",),
     help=(
-        "(Experimental) If set, the backfill will run tasks using the latest 
bundle version instead of "
-        "the version that was active when the original Dag run was created."
+        "(Experimental) The backfill will run tasks using the latest bundle 
version instead of "
+        "the version that was active when the original Dag run was created. 
Defaults to True."
     ),
     action="store_true",
+    default=True,
 )
 
 
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts 
b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
index 440ea0b902b..419f3b2da63 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
@@ -458,6 +458,11 @@ export const $BackfillPostBody = {
             type: 'integer',
             title: 'Max Active Runs',
             default: 10
+        },
+        run_on_latest_version: {
+            type: 'boolean',
+            title: 'Run On Latest Version',
+            default: true
         }
     },
     additionalProperties: false,
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts 
b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
index da93b544463..05391098ac1 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
@@ -126,6 +126,7 @@ export type BackfillPostBody = {
     };
     reprocess_behavior?: ReprocessBehavior;
     max_active_runs?: number;
+    run_on_latest_version?: boolean;
 };
 
 /**
diff --git 
a/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx 
b/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
index 6d15801a05f..5155e482751 100644
--- a/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
@@ -43,9 +43,8 @@ type RunBackfillFormProps = {
   readonly dag: DAGResponse | DAGWithLatestDagRunsResponse;
   readonly onClose: () => void;
 };
-const today = new Date().toISOString().slice(0, 16);
-
 type BackfillFormProps = DagRunTriggerParams & Omit<BackfillPostBody, 
"dag_run_conf">;
+const today = new Date().toISOString().slice(0, 16);
 
 const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => {
   const { t: translate } = useTranslation(["components", "common"]);
@@ -62,6 +61,7 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
       max_active_runs: 1,
       reprocess_behavior: "none",
       run_backwards: false,
+      run_on_latest_version: true,
       to_date: "",
     },
     mode: "onBlur",
@@ -78,6 +78,7 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
         max_active_runs: values.max_active_runs ?? 1,
         reprocess_behavior: values.reprocess_behavior,
         run_backwards: values.run_backwards ?? false,
+        run_on_latest_version: values.run_on_latest_version ?? true,
         to_date: values.to_date ?? "",
       },
     },
@@ -92,16 +93,11 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
       setErrors((prev) => ({ ...prev, date: dateValidationError }));
     }
   }, [dateValidationError]);
-
   useEffect(() => {
     if (conf) {
-      reset((prevValues) => ({
-        ...prevValues,
-        conf,
-      }));
+      reset((prevValues) => ({ ...prevValues, conf }));
     }
   }, [conf, reset]);
-
   const dataIntervalStart = watch("from_date");
   const dataIntervalEnd = watch("to_date");
   const noDataInterval = !Boolean(dataIntervalStart) || 
!Boolean(dataIntervalEnd);
@@ -128,16 +124,8 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
     reset(fdata);
     onClose();
   };
-
-  const resetDateError = () => {
-    setErrors((prev) => ({ ...prev, date: undefined }));
-  };
-
-  const affectedTasks = data ?? {
-    backfills: [],
-    total_entries: 0,
-  };
-
+  const resetDateError = () => setErrors((prev) => ({ ...prev, date: undefined 
}));
+  const affectedTasks = data ?? { backfills: [], total_entries: 0 };
   const inlineMessage = getInlineMessage(isPendingDryRun, 
affectedTasks.total_entries, translate);
 
   return (
@@ -178,12 +166,7 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
           control={control}
           name="reprocess_behavior"
           render={({ field }) => (
-            <RadioCardRoot
-              defaultValue={field.value}
-              onChange={(event) => {
-                field.onChange(event);
-              }}
-            >
+            <RadioCardRoot defaultValue={field.value} 
onChange={field.onChange}>
               <RadioCardLabel fontSize="md" fontWeight="semibold" mb={3}>
                 {translate("backfill.reprocessBehavior")}
               </RadioCardLabel>
@@ -230,6 +213,16 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
           )}
         />
         <Spacer />
+        <Controller
+          control={control}
+          name="run_on_latest_version"
+          render={({ field }) => (
+            <Checkbox checked={field.value} colorPalette="brand" 
onChange={field.onChange}>
+              {translate("dags:runAndTaskActions.options.runOnLatestVersion")}
+            </Checkbox>
+          )}
+        />
+        <Spacer />
         {dag.is_paused ? (
           <>
             <Checkbox
@@ -243,7 +236,6 @@ const RunBackfillForm = ({ dag, onClose }: 
RunBackfillFormProps) => {
             <Spacer />
           </>
         ) : undefined}
-
         <ConfigForm
           control={control}
           errors={errors}
diff --git a/airflow-core/tests/unit/cli/commands/test_backfill_command.py 
b/airflow-core/tests/unit/cli/commands/test_backfill_command.py
index 3e756bfefd2..79d133f84c8 100644
--- a/airflow-core/tests/unit/cli/commands/test_backfill_command.py
+++ b/airflow-core/tests/unit/cli/commands/test_backfill_command.py
@@ -101,7 +101,7 @@ class TestCliBackfill:
             dag_run_conf=None,
             reprocess_behavior=expected_repro,
             triggering_user_name="root",
-            run_on_latest_version=False,
+            run_on_latest_version=True,
         )
 
     @mock.patch("airflow.cli.commands.backfill_command._create_backfill")
@@ -189,7 +189,7 @@ class TestCliBackfill:
             dag_run_conf={"example_key": "example_value"},
             reprocess_behavior=None,
             triggering_user_name="root",
-            run_on_latest_version=False,
+            run_on_latest_version=True,
         )
 
     def test_backfill_with_invalid_dag_run_conf(self):
@@ -235,5 +235,5 @@ class TestCliBackfill:
             dag_run_conf={},
             reprocess_behavior=None,
             triggering_user_name="root",
-            run_on_latest_version=False,
+            run_on_latest_version=True,
         )
diff --git a/airflow-ctl/src/airflowctl/api/datamodels/generated.py 
b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
index 2833a681132..5e2c2078025 100644
--- a/airflow-ctl/src/airflowctl/api/datamodels/generated.py
+++ b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
@@ -1092,6 +1092,7 @@ class BackfillPostBody(BaseModel):
     dag_run_conf: Annotated[dict[str, Any] | None, Field(title="Dag Run 
Conf")] = {}
     reprocess_behavior: ReprocessBehavior | None = "none"
     max_active_runs: Annotated[int | None, Field(title="Max Active Runs")] = 10
+    run_on_latest_version: Annotated[bool | None, Field(title="Run On Latest 
Version")] = True
 
 
 class BackfillResponse(BaseModel):

Reply via email to