Skip to content

fix(api): handle None values in /dags/{dag_id}/tasks order_by parameter#63991

Open
tysoncung wants to merge 1 commit intoapache:mainfrom
tysoncung:fix/63927-tasks-order-by-null-handling
Open

fix(api): handle None values in /dags/{dag_id}/tasks order_by parameter#63991
tysoncung wants to merge 1 commit intoapache:mainfrom
tysoncung:fix/63927-tasks-order-by-null-handling

Conversation

@tysoncung
Copy link
Contributor

Problem

Calling /api/v2/dags/{dag_id}/tasks?order_by=start_date causes a 500 Internal Server Error:

TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'

This happens because task attributes like start_date can be None, and Python's sorted() cannot compare None values using <.

Solution

Introduced a sort key function that:

  1. Uses a tuple (val is None, val) to ensure None values sort to the end
  2. Falls back to an empty string for None to avoid comparison errors
  3. Works correctly for both ascending and descending sort directions

Files Changed

  • airflow-core/src/airflow/api_fastapi/core_api/routes/public/tasks.py

Testing

  • GET /api/v2/dags/{dag_id}/tasks?order_by=start_date → returns tasks sorted with None values at the end (previously 500)
  • GET /api/v2/dags/{dag_id}/tasks?order_by=-start_date → returns tasks reverse-sorted with None values at the end
  • GET /api/v2/dags/{dag_id}/tasks?order_by=task_id → unchanged behavior (no None values)
  • GET /api/v2/dags/{dag_id}/tasks?order_by=invalid_field → still returns 400 Bad Request

Closes #63927

…er (apache#63927)

When sorting tasks by an attribute that may contain None values
(e.g., start_date), Python raises TypeError because None cannot be
compared with '<'. This fix uses a sort key that places None values
at the end of the sorted result, regardless of sort direction.

Closes apache#63927
@henry3260
Copy link
Contributor

Thanks for your PR! Can you add the corresponding tests?

Copy link
Contributor

@SameerMesiah97 SameerMesiah97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic is fine but I'd reassess whether the fallback is needed. Please add a test for this as well.

There are CI failures but they look unrelated.

def _sort_key(task):
val = attrgetter(attr_name)(task)
# Place None values at the end regardless of sort direction
return (val is None, val if val is not None else "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the fallback to empty string necessary? It is unnecessary and introduces a type assumption. The tuple ordering already guarantees safe handling of None, so we can avoid this entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:API Airflow's REST/HTTP API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/dags/{dag_id}/tasks improper null handling for order_by

3 participants