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 b8db2af9cd6 Fix 500 when ordering the Dag list by state or start_date
(#75025)
b8db2af9cd6 is described below
commit b8db2af9cd680ec77f8b213d7ceefffbbf027303
Author: Pushkal Gupta <[email protected]>
AuthorDate: Tue Oct 20 03:06:01 2026 +0530
Fix 500 when ordering the Dag list by state or start_date (#75025)
---
.../airflow/api_fastapi/core_api/openapi/_private_ui.yaml | 4 ++--
.../api_fastapi/core_api/openapi/v2-rest-api-generated.yaml | 4 ++--
.../src/airflow/api_fastapi/core_api/routes/public/dags.py | 2 +-
.../src/airflow/api_fastapi/core_api/routes/ui/dags.py | 2 +-
.../src/airflow/ui/openapi-gen/queries/ensureQueryData.ts | 4 ++--
airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts | 4 ++--
airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts | 4 ++--
airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts | 4 ++--
.../src/airflow/ui/openapi-gen/requests/services.gen.ts | 4 ++--
.../src/airflow/ui/openapi-gen/requests/types.gen.ts | 4 ++--
.../unit/api_fastapi/core_api/routes/public/test_dags.py | 12 ++++++++++++
.../tests/unit/api_fastapi/core_api/routes/ui/test_dags.py | 12 ++++++++++++
12 files changed, 42 insertions(+), 18 deletions(-)
diff --git
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
index f939caedacd..e7bc1eccb2c 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
+++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
@@ -866,13 +866,13 @@ paths:
type: string
description: 'Attributes to order by, multi criteria sort is
supported.
Prefix with `-` for descending order. Supported attributes:
`dag_id, dag_display_name,
- next_dagrun, state, start_date, last_run_state,
last_run_start_date, last_run_run_after`'
+ next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`'
default:
- dag_id
title: Order By
description: 'Attributes to order by, multi criteria sort is
supported. Prefix
with `-` for descending order. Supported attributes: `dag_id,
dag_display_name,
- next_dagrun, state, start_date, last_run_state, last_run_start_date,
last_run_run_after`'
+ next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`'
- name: is_favorite
in: query
required: false
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 aee5e379f22..271ed1d159a 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
@@ -4184,13 +4184,13 @@ paths:
type: string
description: 'Attributes to order by, multi criteria sort is
supported.
Prefix with `-` for descending order. Supported attributes:
`dag_id, dag_display_name,
- next_dagrun, state, start_date, last_run_state,
last_run_start_date`'
+ next_dagrun, last_run_state, last_run_start_date`'
default:
- dag_id
title: Order By
description: 'Attributes to order by, multi criteria sort is
supported. Prefix
with `-` for descending order. Supported attributes: `dag_id,
dag_display_name,
- next_dagrun, state, start_date, last_run_state, last_run_start_date`'
+ next_dagrun, last_run_state, last_run_start_date`'
- name: is_favorite
in: query
required: false
diff --git
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py
index 7059b9992ba..8d3c8e08387 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py
@@ -129,7 +129,7 @@ def get_dags(
SortParam,
Depends(
SortParam(
- ["dag_id", "dag_display_name", "next_dagrun", "state",
"start_date"],
+ ["dag_id", "dag_display_name", "next_dagrun"],
DagModel,
{"last_run_state": DagRun.state, "last_run_start_date":
DagRun.start_date},
).dynamic_depends()
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
index 23886e8840b..d011fa4c2ff 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
@@ -136,7 +136,7 @@ def get_dags(
SortParam,
Depends(
SortParam(
- ["dag_id", "dag_display_name", "next_dagrun", "state",
"start_date"],
+ ["dag_id", "dag_display_name", "next_dagrun"],
DagModel,
{
"last_run_state": DagRun.state,
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
index 426338f18ec..76133b1f85e 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
@@ -781,7 +781,7 @@ export const ensureUseDagWarningServiceListDagWarningsData
= (queryClient: Query
* @param data.dagRunEndDateLte
* @param data.dagRunEndDateLt
* @param data.dagRunState
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date`
* @param data.isFavorite
* @param data.timetableType
* @returns DAGCollectionResponse Successful Response
@@ -886,7 +886,7 @@ export const ensureUseDagServiceGetDagTagsData =
(queryClient: QueryClient, { li
* @param data.bundleName
* @param data.bundleVersion
* @param data.relativeFilelocPrefix Filter Dags by the folder (directory of
``relative_fileloc``) they live in. Matches the given folder and all of its
subfolders.
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date, last_run_run_after`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`
* @param data.isFavorite
* @param data.hasAssetSchedule Filter Dags with asset-based scheduling
* @param data.assetDependency Filter Dags by asset dependency (name or URI)
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
index 2a3c519a9c8..7d646a03e8e 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
@@ -781,7 +781,7 @@ export const prefetchUseDagWarningServiceListDagWarnings =
(queryClient: QueryCl
* @param data.dagRunEndDateLte
* @param data.dagRunEndDateLt
* @param data.dagRunState
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date`
* @param data.isFavorite
* @param data.timetableType
* @returns DAGCollectionResponse Successful Response
@@ -886,7 +886,7 @@ export const prefetchUseDagServiceGetDagTags =
(queryClient: QueryClient, { limi
* @param data.bundleName
* @param data.bundleVersion
* @param data.relativeFilelocPrefix Filter Dags by the folder (directory of
``relative_fileloc``) they live in. Matches the given folder and all of its
subfolders.
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date, last_run_run_after`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`
* @param data.isFavorite
* @param data.hasAssetSchedule Filter Dags with asset-based scheduling
* @param data.assetDependency Filter Dags by asset dependency (name or URI)
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
index 03a2a716e0f..d2e58f17ca1 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
@@ -781,7 +781,7 @@ export const useDagWarningServiceListDagWarnings = <TData =
Common.DagWarningSer
* @param data.dagRunEndDateLte
* @param data.dagRunEndDateLt
* @param data.dagRunState
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date`
* @param data.isFavorite
* @param data.timetableType
* @returns DAGCollectionResponse Successful Response
@@ -886,7 +886,7 @@ export const useDagServiceGetDagTags = <TData =
Common.DagServiceGetDagTagsDefau
* @param data.bundleName
* @param data.bundleVersion
* @param data.relativeFilelocPrefix Filter Dags by the folder (directory of
``relative_fileloc``) they live in. Matches the given folder and all of its
subfolders.
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date, last_run_run_after`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`
* @param data.isFavorite
* @param data.hasAssetSchedule Filter Dags with asset-based scheduling
* @param data.assetDependency Filter Dags by asset dependency (name or URI)
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
index 299870edff3..7c83461a6ab 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
@@ -781,7 +781,7 @@ export const useDagWarningServiceListDagWarningsSuspense =
<TData = Common.DagWa
* @param data.dagRunEndDateLte
* @param data.dagRunEndDateLt
* @param data.dagRunState
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date`
* @param data.isFavorite
* @param data.timetableType
* @returns DAGCollectionResponse Successful Response
@@ -886,7 +886,7 @@ export const useDagServiceGetDagTagsSuspense = <TData =
Common.DagServiceGetDagT
* @param data.bundleName
* @param data.bundleVersion
* @param data.relativeFilelocPrefix Filter Dags by the folder (directory of
``relative_fileloc``) they live in. Matches the given folder and all of its
subfolders.
-* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date, last_run_run_after`
+* @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`
* @param data.isFavorite
* @param data.hasAssetSchedule Filter Dags with asset-based scheduling
* @param data.assetDependency Filter Dags by asset dependency (name or URI)
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 2aedd73b91e..5e5fb1e981d 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
@@ -1936,7 +1936,7 @@ export class DagService {
* @param data.dagRunEndDateLte
* @param data.dagRunEndDateLt
* @param data.dagRunState
- * @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date`
+ * @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date`
* @param data.isFavorite
* @param data.timetableType
* @returns DAGCollectionResponse Successful Response
@@ -2273,7 +2273,7 @@ export class DagService {
* @param data.bundleName
* @param data.bundleVersion
* @param data.relativeFilelocPrefix Filter Dags by the folder (directory
of ``relative_fileloc``) they live in. Matches the given folder and all of its
subfolders.
- * @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, state, start_date, last_run_state,
last_run_start_date, last_run_run_after`
+ * @param data.orderBy Attributes to order by, multi criteria sort is
supported. Prefix with `-` for descending order. Supported attributes: `dag_id,
dag_display_name, next_dagrun, last_run_state, last_run_start_date,
last_run_run_after`
* @param data.isFavorite
* @param data.hasAssetSchedule Filter Dags with asset-based scheduling
* @param data.assetDependency Filter Dags by asset dependency (name or
URI)
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 d55498a3c66..5321f56062b 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
@@ -4164,7 +4164,7 @@ export type GetDagsData = {
limit?: number;
offset?: number;
/**
- * Attributes to order by, multi criteria sort is supported. Prefix with
`-` for descending order. Supported attributes: `dag_id, dag_display_name,
next_dagrun, state, start_date, last_run_state, last_run_start_date`
+ * Attributes to order by, multi criteria sort is supported. Prefix with
`-` for descending order. Supported attributes: `dag_id, dag_display_name,
next_dagrun, last_run_state, last_run_start_date`
*/
orderBy?: Array<(string)>;
owners?: Array<(string)>;
@@ -4309,7 +4309,7 @@ export type GetDagsUiData = {
limit?: number;
offset?: number;
/**
- * Attributes to order by, multi criteria sort is supported. Prefix with
`-` for descending order. Supported attributes: `dag_id, dag_display_name,
next_dagrun, state, start_date, last_run_state, last_run_start_date,
last_run_run_after`
+ * Attributes to order by, multi criteria sort is supported. Prefix with
`-` for descending order. Supported attributes: `dag_id, dag_display_name,
next_dagrun, last_run_state, last_run_start_date, last_run_run_after`
*/
orderBy?: Array<(string)>;
owners?: Array<(string)>;
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
index 3b6c6d283eb..5c184bfb784 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
@@ -775,6 +775,18 @@ class TestGetDags(TestDagEndpoint):
assert body["total_entries"] == 2
assert [dag["dag_id"] for dag in body["dags"]] == [DAG1_ID, DAG2_ID]
+ @pytest.mark.parametrize("order_by", ["state", "start_date", "-state"])
+ def test_rejects_sort_by_dag_run_column_names(self, test_client, order_by):
+ # #44345 moved these two behind `last_run_state` and
`last_run_start_date` in `to_replace`
+ # but left the DagRun column names in the allowed list, so the spec
advertised them and
+ # sorting by either raised AttributeError on DagModel.
+ response = test_client.get("/dags", params={"order_by": order_by})
+ assert response.status_code == 400
+ assert response.json()["detail"] == (
+ f"Ordering with '{order_by.lstrip('-')}' is disallowed or "
+ f"the attribute does not exist on the model"
+ )
+
@pytest.mark.parametrize(
("setup_favorites", "expected_total_entries", "expected_ids"),
[
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
index dcee4b1a86b..ce504955e7e 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
@@ -547,6 +547,18 @@ class TestGetDagRuns(TestPublicDagEndpoint):
assert response.status_code == 200
assert [dag["dag_id"] for dag in response.json()["dags"]] == [DAG2_ID,
DAG1_ID]
+ @pytest.mark.parametrize("order_by", ["state", "start_date", "-state"])
+ def test_rejects_sort_by_dag_run_column_names(self, test_client, order_by):
+ # #44345 moved these two behind `last_run_state` and
`last_run_start_date` in `to_replace`
+ # but left the DagRun column names in the allowed list, so the spec
advertised them and
+ # sorting by either raised AttributeError on DagModel.
+ response = test_client.get("/dags", params={"order_by": order_by})
+ assert response.status_code == 400
+ assert response.json()["detail"] == (
+ f"Ordering with '{order_by.lstrip('-')}' is disallowed or "
+ f"the attribute does not exist on the model"
+ )
+
def test_get_dags_no_n_plus_one_queries(self, session, test_client):
"""Test that fetching DAGs with tags doesn't trigger n+1 queries."""
num_dags = 5