Skip to content

Fix TypeError clearing a DAG run when a queued-at deadline interval is stored as JSON - #70370

Open
hkc-8010 wants to merge 2 commits into
apache:mainfrom
hkc-8010:fix/deadline-interval-clear-recalc
Open

Fix TypeError clearing a DAG run when a queued-at deadline interval is stored as JSON#70370
hkc-8010 wants to merge 2 commits into
apache:mainfrom
hkc-8010:fix/deadline-interval-clear-recalc

Conversation

@hkc-8010

Copy link
Copy Markdown
Contributor

Summary

Clearing a DAG run or task instance whose DAG defines a deadline referencing the run's queued-at time (DeadlineReference.DAGRUN_QUEUED_AT) raised TypeError: unsupported type for timedelta seconds component: dict and surfaced as an HTTP 500 in the API server.

Since 3.3.0 the deadline_alert.interval column is JSON (migration 0117_3_3_0_change_deadline_interval_to_json.py, from #64751), holding a serialized timedelta or VariableInterval, e.g. {"__classname__": "datetime.timedelta", "__version__": 2, "__data__": 3600.0}. _recalculate_dagrun_queued_at_deadlines (called from clear_task_instances) still passed that raw dict into timedelta(seconds=...). Every other consumer (DagRun creation in serialization/definitions/dag.py, the model __repr__) decodes the JSON first; only the clear path was missed.

The fix decodes the interval the same way DagRun creation does, via decode_deadline_alert, then resolves a VariableInterval to a timedelta before recalculating.

Changes

  • airflow-core/src/airflow/models/taskinstance.py: decode the JSON interval via decode_deadline_alert and resolve VariableInterval in _recalculate_dagrun_queued_at_deadlines.
  • airflow-core/tests/unit/models/test_taskinstance.py: the existing test stored the interval as a plain float, so it never exercised the JSON path. It now stores the serialized envelope and is parametrized over a fixed timedelta and a VariableInterval. Both cases fail on main with the reported TypeError and pass with the fix.

closes: #70368

PR Checklist

  • Targeted at the main branch
  • Tests added (fixed-interval and VariableInterval cases, both reproduce the bug on main)
  • prek hooks pass on the changed files (ruff, ruff-format, mypy for airflow-core)

…s stored as JSON

Since 3.3.0 the deadline_alert.interval column is JSON (migration 0117, apache#64751),
holding a serialized timedelta or VariableInterval. _recalculate_dagrun_queued_at_deadlines
still passed that raw dict into timedelta(seconds=...), so clearing a DAG run or task
instance whose DAG has a DagRunQueuedAtDeadline failed with
"TypeError: unsupported type for timedelta seconds component: dict" (HTTP 500).

Decode the interval the same way DagRun creation does (decode_deadline_alert), then
resolve a VariableInterval to a timedelta before recalculating. The existing test stored
the interval as a plain float and never exercised the JSON path; it now stores the
serialized envelope and is parametrized over fixed-timedelta and VariableInterval.

closes: apache#70368
@hkc-8010
hkc-8010 requested review from XD-DENG and ashb as code owners July 24, 2026 09:04
@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 28, 2026
@eladkal eladkal added this to the Airflow 3.3.2 milestone Aug 5, 2026
@eladkal eladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 5, 2026
return

# Local imports to avoid a circular import between models and serialization.
from airflow.sdk.definitions.deadline import VariableInterval

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't like the SDK import here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It reintroduces coupling between Task SDK (client) and Scheduler/API-server (server)

@amoghrajesh amoghrajesh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This propagates the same coupling I raised in #64751 - isinstance(interval, VariableInterval) here imports airflow.sdk.definitions.deadline.VariableInterval into core airflow at runtime. See #64751 (review) for details.

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

Labels

backport-to-v3-3-test Backport to v3-3-test ready for maintainer review Set after triaging when all criteria pass. type:bug-fix Changelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clearing a DAG run/task instance with a DagRunQueuedAtDeadline fails with TypeError: unsupported type for timedelta seconds component: dict

5 participants