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

potiuk 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 85842d4082b Added state validation to delete dag run endpoint (#60195)
85842d4082b is described below

commit 85842d4082bf7d5a0da7574694f9231fb8dc3913
Author: Justin Pakzad <[email protected]>
AuthorDate: Wed Jan 7 06:02:57 2026 -0500

    Added state validation to delete dag run endpoint (#60195)
---
 .../api_fastapi/core_api/routes/public/dag_run.py       | 10 ++++++++++
 .../api_fastapi/core_api/routes/public/test_dag_run.py  | 17 +++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py 
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
index ae644e6cfc2..d85c137c6ca 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
@@ -132,12 +132,22 @@ def get_dag_run(dag_id: str, dag_run_id: str, session: 
SessionDep) -> DAGRunResp
 def delete_dag_run(dag_id: str, dag_run_id: str, session: SessionDep):
     """Delete a DAG Run entry."""
     dag_run = session.scalar(select(DagRun).filter_by(dag_id=dag_id, 
run_id=dag_run_id))
+    deletable_states = {s.value for s in DAGRunPatchStates}
 
     if dag_run is None:
         raise HTTPException(
             status.HTTP_404_NOT_FOUND,
             f"The DagRun with dag_id: `{dag_id}` and run_id: `{dag_run_id}` 
was not found",
         )
+    if dag_run.state not in deletable_states:
+        raise HTTPException(
+            status.HTTP_409_CONFLICT,
+            (
+                f"The DagRun with dag_id: `{dag_id}` and run_id: 
`{dag_run_id}` "
+                f"cannot be deleted in {dag_run.state} state"
+            ),
+        )
+
     session.delete(dag_run)
 
 
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py
index 3720994e04d..87a7b932b74 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_run.py
@@ -1322,6 +1322,23 @@ class TestDeleteDagRun:
         body = response.json()
         assert body["detail"] == "The DagRun with dag_id: `test_dag1` and 
run_id: `invalid` was not found"
 
+    def test_delete_dag_run_in_running_state(self, test_client, dag_maker, 
session):
+        with dag_maker(dag_id="test_running_dag"):
+            EmptyOperator(task_id="t1")
+
+        dag_maker.create_dagrun(
+            run_id="test_running",
+            state=DagRunState.RUNNING,
+        )
+        session.commit()
+        response = 
test_client.delete("/dags/test_running_dag/dagRuns/test_running")
+        assert response.status_code == 409
+        body = response.json()
+        assert body["detail"] == (
+            "The DagRun with dag_id: `test_running_dag` and run_id: 
`test_running` "
+            "cannot be deleted in running state"
+        )
+
     def test_should_respond_401(self, unauthenticated_test_client):
         response = 
unauthenticated_test_client.delete(f"/dags/{DAG1_ID}/dagRuns/invalid")
         assert response.status_code == 401

Reply via email to