dstandish opened a new issue, #71455:
URL: https://github.com/apache/airflow/issues/71455

   ## Problem
   
   `_get_new_task_ids` 
(`airflow-core/src/airflow/models/taskinstance.py:270-309`), which powers the 
`only_new` clear feature added in #59764, computes "tasks added since this 
run's version" like this:
   
   ```python
   # Use created_dag_version_id directly to get the DAG version the run was
   # originally created with. We cannot use get_dag_for_run here because it
   # falls back to the latest version when bundle_version is not set (e.g.
   # LocalDagBundle), which would make current_dag == latest_dag and the diff
   # always empty.
   current_dag = None
   if dag_run.created_dag_version_id:
       current_dag = 
scheduler_dagbag.get_dag(version_id=dag_run.created_dag_version_id, 
session=session)
   new_task_ids = set(latest_dag.task_ids) - set(current_dag.task_ids) if 
current_dag else set()
   ```
   
   The comment explicitly documents the assumption that 
`created_dag_version_id` means "the version the run was originally created 
with." That assumption was correct when the field was immutable. Since #54984, 
`clear_task_instances(..., run_on_latest_version=True)` mutates 
`created_dag_version_id` to the latest version for a pinned run (while only 
bumping `dag_version_id` on the specific task instances that were cleared — see 
`taskinstance.py:477`). No new task-instance rows get created by that 
operation; it only updates the pointer and the already-existing, cleared TIs.
   
   Once that has happened, `created_dag_version_id == latest`, so `current_dag 
== latest_dag`, and `new_task_ids` becomes `latest_dag.task_ids - 
latest_dag.task_ids` = the empty set — even if the run genuinely never got a 
task instance created for a task that was added between the run's true original 
version and latest.
   
   ## Repro
   
   1. Create a pinned DagRun at version V1 with tasks A and B.
   2. Deploy V2, which adds task C (V2 task_ids = {A, B, C}).
   3. Clear task A with `run_on_latest_version=True`. Now 
`dag_run.created_dag_version_id == V2`; the run still has no TI for task C.
   4. Run an `only_new` clear on this DagRun.
   
   ## Expected
   
   Task C is identified as new and a TaskInstance is created for it.
   
   ## Actual
   
   `_get_new_task_ids` returns an empty set (`current_dag` resolves to V2, same 
as `latest_dag`), so task C is silently never added, even though the run's 
actual task-instance rows never picked it up.
   
   ## Suggested fix
   
   Determine "already has a TI for task X" by checking the run's actual 
`TaskInstance` rows directly (e.g. `{ti.task_id for ti in 
dag_run.get_task_instances(session=session)}`) rather than by diffing against a 
dag-version pointer (`created_dag_version_id`) that can no longer be trusted to 
represent "the version whose task set defines this run's existing task 
instances."
   
   ## Context
   
   This is one concrete consequence of `created_dag_version_id`'s contract 
having drifted from "the version recorded at DagRun creation" (its documented 
meaning) to "the version this run should currently run at" (its behavior since 
#54984). See the companion issue tracking that broader contract problem: #71453
   
   ---
   Drafted-by: Claude Code (Sonnet 5) (no human review before posting)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to