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"})