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

shahar1 pushed a commit to branch airflow-ctl/v0-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/airflow-ctl/v0-1-test by this 
push:
     new ba11d6dd238 [airflow-ctl/v0-1-test] Reject non-positive 
max_active_runs when creating a backfill (#75071) (#75380)
ba11d6dd238 is described below

commit ba11d6dd238bc34f5856e86da24cab3a98085cc7
Author: W. H. Wang <[email protected]>
AuthorDate: Sat Oct 31 01:07:26 2026 +0800

    [airflow-ctl/v0-1-test] Reject non-positive max_active_runs when creating a 
backfill (#75071) (#75380)
    
    (cherry picked from commit 7d94a66507ed1085f2e9773453e6fd355aa0bd77)
---
 .../api_fastapi/core_api/datamodels/backfills.py   |  2 +-
 .../core_api/openapi/v2-rest-api-generated.yaml    |  1 +
 .../airflow/ui/openapi-gen/requests/schemas.gen.ts |  1 +
 .../core_api/routes/public/test_backfills.py       | 28 ++++++++++++++++++++++
 .../src/airflowctl/api/datamodels/generated.py     |  2 +-
 5 files changed, 32 insertions(+), 2 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 87d2677028e..669e1e4daf1 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
@@ -35,7 +35,7 @@ class BackfillPostBody(StrictBaseModel):
     run_backwards: bool = False
     dag_run_conf: dict = {}
     reprocess_behavior: ReprocessBehavior = ReprocessBehavior.NONE
-    max_active_runs: int = 10
+    max_active_runs: int = Field(default=10, ge=1)
     run_on_latest_version: bool = True
 
 
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 b1ff3742ddd..4ddd9d82042 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
@@ -9242,6 +9242,7 @@ components:
           default: none
         max_active_runs:
           type: integer
+          minimum: 1.0
           title: Max Active Runs
           default: 10
         run_on_latest_version:
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 00c5c22b509..63c051cd1b8 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
@@ -456,6 +456,7 @@ export const $BackfillPostBody = {
         },
         max_active_runs: {
             type: 'integer',
+            minimum: 1,
             title: 'Max Active Runs',
             default: 10
         },
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_backfills.py 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_backfills.py
index 10bfd0f7817..ef4fe97f969 100644
--- 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_backfills.py
+++ 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_backfills.py
@@ -279,6 +279,20 @@ class TestCreateBackfill(TestBackfillEndpoint):
         assert response.status_code == 404
         assert response.json().get("detail") == "Could not find dag 
DAG_NOT_EXIST"
 
+    @pytest.mark.parametrize("max_active_runs", [0, -3])
+    def test_create_backfill_rejects_non_positive_max_active_runs(self, 
max_active_runs, test_client):
+        response = test_client.post(
+            url="/backfills",
+            json={
+                "dag_id": "TEST_DAG_1",
+                "from_date": "2024-01-01T00:00:00Z",
+                "to_date": "2024-01-02T00:00:00Z",
+                "max_active_runs": max_active_runs,
+            },
+        )
+        assert response.status_code == 422
+        assert response.json()["detail"][0]["loc"] == ["body", 
"max_active_runs"]
+
     def test_no_schedule_dag(self, session, dag_maker, test_client):
         with dag_maker(session=session, dag_id="TEST_DAG_1", schedule="None") 
as dag:
             EmptyOperator(task_id="mytask")
@@ -757,6 +771,20 @@ class TestCreateBackfillDryRun(TestBackfillEndpoint):
         response_json = response.json()
         assert response_json["backfills"] == expected_dates
 
+    @pytest.mark.parametrize("max_active_runs", [0, -3])
+    def 
test_create_backfill_dry_run_rejects_non_positive_max_active_runs(self, 
max_active_runs, test_client):
+        response = test_client.post(
+            url="/backfills/dry_run",
+            json={
+                "dag_id": "TEST_DAG_1",
+                "from_date": "2024-01-01T00:00:00Z",
+                "to_date": "2024-01-02T00:00:00Z",
+                "max_active_runs": max_active_runs,
+            },
+        )
+        assert response.status_code == 422
+        assert response.json()["detail"][0]["loc"] == ["body", 
"max_active_runs"]
+
     @pytest.mark.parametrize(
         ("repro_act", "repro_exp", "run_backwards", "status_code"),
         [
diff --git a/airflow-ctl/src/airflowctl/api/datamodels/generated.py 
b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
index 8824a8484ed..6983b39dc07 100644
--- a/airflow-ctl/src/airflowctl/api/datamodels/generated.py
+++ b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
@@ -1114,7 +1114,7 @@ class BackfillPostBody(BaseModel):
     run_backwards: Annotated[bool | None, Field(title="Run Backwards")] = False
     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
+    max_active_runs: Annotated[int | None, Field(ge=1, title="Max Active 
Runs")] = 10
     run_on_latest_version: Annotated[bool | None, Field(title="Run On Latest 
Version")] = True
 
 

Reply via email to