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

bbovenzi 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 ec751185e3d Add missing dag_id filter on DagRun query (#62750)
ec751185e3d is described below

commit ec751185e3d9727e24dbddbce1394152813d7bc5
Author: Jeff Stein <[email protected]>
AuthorDate: Fri Mar 6 08:26:43 2026 -0800

    Add missing dag_id filter on DagRun query (#62750)
---
 .../api_fastapi/core_api/openapi/v2-rest-api-generated.yaml   |  6 ++++++
 .../api_fastapi/core_api/routes/public/task_instances.py      | 11 ++++++++---
 .../src/airflow/ui/openapi-gen/requests/services.gen.ts       |  1 +
 airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts |  4 ++++
 .../api_fastapi/core_api/routes/public/test_task_instances.py |  8 +++++---
 5 files changed, 24 insertions(+), 6 deletions(-)

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 5ece802761c..d3955872f71 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
@@ -6947,6 +6947,12 @@ paths:
               schema:
                 $ref: '#/components/schemas/HTTPExceptionResponse'
           description: Forbidden
+        '400':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/HTTPExceptionResponse'
+          description: Bad Request
         '404':
           content:
             application/json:
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py 
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
index 9e9350bb75b..10ea000ace9 100644
--- 
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
+++ 
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
@@ -410,7 +410,7 @@ def get_mapped_task_instance(
 
 @task_instances_router.get(
     task_instances_prefix,
-    responses=create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND]),
+    responses=create_openapi_http_exception_doc([status.HTTP_400_BAD_REQUEST, 
status.HTTP_404_NOT_FOUND]),
     dependencies=[Depends(requires_access_dag(method="GET", 
access_entity=DagAccessEntity.TASK_INSTANCE))],
 )
 def get_task_instances(
@@ -484,11 +484,16 @@ def get_task_instances(
         
select(TI).join(TI.dag_run).outerjoin(TI.dag_version).options(*eager_load_TI_and_TIH_for_validation())
     )
     if dag_run_id != "~":
-        dag_run = session.scalar(select(DagRun).filter_by(run_id=dag_run_id))
+        if dag_id == "~":
+            raise HTTPException(
+                status.HTTP_400_BAD_REQUEST,
+                "dag_id is required when dag_run_id is specified",
+            )
+        dag_run = session.scalar(select(DagRun).where(DagRun.dag_id == dag_id, 
DagRun.run_id == dag_run_id))
         if not dag_run:
             raise HTTPException(
                 status.HTTP_404_NOT_FOUND,
-                f"DagRun with run_id: `{dag_run_id}` was not found",
+                f"DagRun with dag_id: `{dag_id}` and run_id: `{dag_run_id}` 
was not found",
             )
         query = query.where(TI.run_id == dag_run_id)
     if dag_id != "~":
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts 
b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
index ec616b7e2bc..6318b4678f3 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
@@ -2413,6 +2413,7 @@ export class TaskInstanceService {
                 order_by: data.orderBy
             },
             errors: {
+                400: 'Bad Request',
                 401: 'Unauthorized',
                 403: 'Forbidden',
                 404: 'Not Found',
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 2a92af9ca3c..db34d1f2548 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
@@ -5539,6 +5539,10 @@ export type $OpenApiTs = {
                  * Successful Response
                  */
                 200: TaskInstanceCollectionResponse;
+                /**
+                 * Bad Request
+                 */
+                400: HTTPExceptionResponse;
                 /**
                  * Unauthorized
                  */
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
index b34f7fc13c6..4a0ef3e1be9 100644
--- 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
+++ 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
@@ -1499,9 +1499,11 @@ class TestGetTaskInstances(TestTaskInstanceEndpoint):
         assert response.status_code == 404
         assert response.json() == {"detail": "The Dag with ID: `invalid` was 
not found"}
 
-        response = test_client.get("/dags/~/dagRuns/invalid/taskInstances")
-        assert response.status_code == 404
-        assert response.json() == {"detail": "DagRun with run_id: `invalid` 
was not found"}
+    def test_dag_id_required_when_dag_run_id_specified(self, test_client):
+        # dag_run_id is not unique - it requires dag_id to identify a specific 
dag_run
+        response = test_client.get("/dags/~/dagRuns/some_run_id/taskInstances")
+        assert response.status_code == 400
+        assert response.json() == {"detail": "dag_id is required when 
dag_run_id is specified"}
 
     def test_bad_state(self, test_client):
         response = test_client.get("/dags/~/dagRuns/~/taskInstances", 
params={"state": "invalid"})

Reply via email to