This is an automated email from the ASF dual-hosted git repository.
choo121600 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 153623856ef Prevent AlreadyRunningBackfill error caused by invalid
date range request (#66874)
153623856ef is described below
commit 153623856efb44a3f60ef9fdb67e22e05609e067
Author: Park Jiwon <[email protected]>
AuthorDate: Thu May 21 00:37:36 2026 +0900
Prevent AlreadyRunningBackfill error caused by invalid date range request
(#66874)
* fix: raise InvalidBackfillDate if from_date is after to_date
* test: valid InvalidBackfillDate Exception when backfill parameter
from_date is after to_date
* feat: add exception InvalidBackfillDateRange
- ambigous meaning of InvalidBackfillDate
---
.../api_fastapi/core_api/routes/public/backfills.py | 3 +++
airflow-core/src/airflow/models/backfill.py | 21 ++++++++++++++++++---
airflow-core/tests/unit/models/test_backfill.py | 18 ++++++++++++++++++
3 files changed, 39 insertions(+), 3 deletions(-)
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 4bf6084727c..c8ba0b7be96 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
@@ -52,6 +52,7 @@ from airflow.models.backfill import (
DagNonPeriodicScheduleException,
InvalidBackfillConf,
InvalidBackfillDate,
+ InvalidBackfillDateRange,
InvalidBackfillDirection,
InvalidReprocessBehavior,
_create_backfill,
@@ -265,6 +266,7 @@ def create_backfill(
InvalidBackfillDirection,
DagNonPeriodicScheduleException,
InvalidBackfillDate,
+ InvalidBackfillDateRange,
InvalidBackfillConf,
) as e:
raise RequestValidationError(str(e))
@@ -319,6 +321,7 @@ def create_backfill_dry_run(
InvalidBackfillDirection,
DagNonPeriodicScheduleException,
InvalidBackfillDate,
+ InvalidBackfillDateRange,
InvalidBackfillConf,
) as e:
raise RequestValidationError(str(e))
diff --git a/airflow-core/src/airflow/models/backfill.py
b/airflow-core/src/airflow/models/backfill.py
index d482f7b7220..96b7535ecfe 100644
--- a/airflow-core/src/airflow/models/backfill.py
+++ b/airflow-core/src/airflow/models/backfill.py
@@ -107,6 +107,14 @@ class InvalidBackfillDate(AirflowException):
"""
+class InvalidBackfillDateRange(AirflowException):
+ """
+ Raised when from_date is after to_date in a backfill request.
+
+ :meta private:
+ """
+
+
class InvalidBackfillConf(AirflowException):
"""
Raised when the provided ``dag_run_conf`` fails validation against the
DAG's params.
@@ -266,6 +274,16 @@ def _validate_backfill_params(
reprocess_behavior: ReprocessBehavior | None,
dag_run_conf: dict | None = None,
) -> None:
+
+ if from_date > to_date:
+ raise InvalidBackfillDateRange(
+ f"from_date ({from_date.isoformat()}) must not be after to_date
({to_date.isoformat()})."
+ )
+
+ current_time = timezone.utcnow()
+ if from_date >= current_time and to_date >= current_time:
+ raise InvalidBackfillDate("Backfill cannot be executed for future
dates.")
+
depends_on_past = any(x.depends_on_past for x in dag.tasks)
if depends_on_past:
if reverse is True:
@@ -277,9 +295,6 @@ def _validate_backfill_params(
"Dag has tasks for which depends_on_past=True. "
"You must set reprocess behavior to reprocess completed or
reprocess failed."
)
- current_time = timezone.utcnow()
- if from_date >= current_time and to_date >= current_time:
- raise InvalidBackfillDate("Backfill cannot be executed for future
dates.")
if dag_run_conf is not None:
try:
dag.params.deep_merge(dag_run_conf).validate()
diff --git a/airflow-core/tests/unit/models/test_backfill.py
b/airflow-core/tests/unit/models/test_backfill.py
index 5ed2a0debc6..d5f36b78bf8 100644
--- a/airflow-core/tests/unit/models/test_backfill.py
+++ b/airflow-core/tests/unit/models/test_backfill.py
@@ -34,6 +34,7 @@ from airflow.models.backfill import (
BackfillDagRunExceptionReason,
DagNonPeriodicScheduleException,
InvalidBackfillConf,
+ InvalidBackfillDateRange,
InvalidBackfillDirection,
InvalidReprocessBehavior,
ReprocessBehavior,
@@ -838,3 +839,20 @@ def
test_do_dry_run_non_periodic_schedule_rejected(schedule, dag_kwargs, dag_mak
session=session,
)
)
+
+
+def test_create_backfill_from_date_after_to_date_raises(dag_maker, session):
+ with dag_maker(schedule="@daily") as dag:
+ PythonOperator(task_id="hi", python_callable=print)
+ session.commit()
+
+ with pytest.raises(InvalidBackfillDateRange, match="must not be after
to_date"):
+ _create_backfill(
+ dag_id=dag.dag_id,
+ from_date=pendulum.parse("2026-05-13"),
+ to_date=pendulum.parse("2026-05-12"),
+ max_active_runs=2,
+ reverse=False,
+ triggering_user_name="pytest",
+ dag_run_conf={},
+ )