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