Under which category would you file this issue?
Airflow Core
Apache Airflow version
3.3.1
What happened and how to reproduce it?
Marking a Dag run as success or failed from the UI returns 409 Conflict
("Update Dag Run Request Failed"), but the change is applied anyway - the run
and its task instances are updated, and the UI shows an error for an operation
that actually succeeded.
It only happens the first time a given run is marked. Marking the same run
again succeeds with no error.
The api-server log shows:
Error with id ..., statement: INSERT INTO dag_run_note (user_id, dag_run_id, content, created_at, updated_at) VALUES (...)
i.e. a duplicate-key violation on dag_run_note, surfaced as 409 by
_UniqueConstraintErrorHandler. It happens even with the Note field left empty.
Works correctly in 3.3.0.
To reproduce:
- Fresh 3.3.1 install, Postgres, any Dag.
- Trigger a run and leave it un-started.
- Mark the run as success (or failed) from the UI, leaving the Note box empty.
- The red "Conflict" toast appears; the run is nevertheless marked and its
task instances updated.
- Mark the same run again - this time it succeeds silently.
What you think should happen instead?
The request should return 200 and no duplicate insert should be attempted.
The cause is in _set_dag_run_terminal_state
(airflow-core/src/airflow/api/common/mark_tasks.py):
for ti in pending_normal_tis:
ti.set_state(TaskInstanceState.SKIPPED)
TaskInstance.set_state is decorated with @provide_session and no session is
passed here, so it opens its own session, calls session.merge(self) and
commits it. TaskInstance.dag_run is lazy="joined", so that merge cascades
TI → DagRun → dag_run_note and carries the still-unflushed DagRunNote into
the second session, which commits it. The request's session then commits its
own copy of the same row, and the second insert violates dag_run_note_pkey.
This surfaces in 3.3.1 because patch_dag_run now applies the note before the
state, so a note is attached to the DagRun at the moment that merge happens. In
3.3.0 the state ran first and there was nothing to cascade.
The fix is to pass the session through:
for ti in pending_normal_tis:
ti.set_state(TaskInstanceState.SKIPPED, session=session)
That keeps the note-before-state ordering intact and produces a single insert.
Verified locally on 3.3.1: the 409 is gone, and the run and its task instances
update as expected.
Operating System
macOS
Deployment
Other
Apache Airflow Provider(s)
No response
Versions of Apache Airflow Providers
No response
Official Helm Chart version
Not Applicable
Kubernetes Version
No response
Helm Chart configuration
No response
Docker Image customizations
No response
Anything else?
No response
Are you willing to submit PR?
Code of Conduct
Under which category would you file this issue?
Airflow Core
Apache Airflow version
3.3.1
What happened and how to reproduce it?
Marking a Dag run as success or failed from the UI returns
409 Conflict("Update Dag Run Request Failed"), but the change is applied anyway - the run
and its task instances are updated, and the UI shows an error for an operation
that actually succeeded.
It only happens the first time a given run is marked. Marking the same run
again succeeds with no error.
The api-server log shows:
Error with id ..., statement: INSERT INTO dag_run_note (user_id, dag_run_id, content, created_at, updated_at) VALUES (...)i.e. a duplicate-key violation on
dag_run_note, surfaced as 409 by_UniqueConstraintErrorHandler. It happens even with the Note field left empty.Works correctly in 3.3.0.
To reproduce:
task instances updated.
What you think should happen instead?
The request should return 200 and no duplicate insert should be attempted.
The cause is in
_set_dag_run_terminal_state(
airflow-core/src/airflow/api/common/mark_tasks.py):TaskInstance.set_stateis decorated with@provide_sessionand no session ispassed here, so it opens its own session, calls
session.merge(self)andcommits it.
TaskInstance.dag_runislazy="joined", so that merge cascadesTI → DagRun →
dag_run_noteand carries the still-unflushedDagRunNoteintothe second session, which commits it. The request's session then commits its
own copy of the same row, and the second insert violates
dag_run_note_pkey.This surfaces in 3.3.1 because
patch_dag_runnow applies the note before thestate, so a note is attached to the DagRun at the moment that merge happens. In
3.3.0 the state ran first and there was nothing to cascade.
The fix is to pass the session through:
That keeps the note-before-state ordering intact and produces a single insert.
Verified locally on 3.3.1: the 409 is gone, and the run and its task instances
update as expected.
Operating System
macOS
Deployment
Other
Apache Airflow Provider(s)
No response
Versions of Apache Airflow Providers
No response
Official Helm Chart version
Not Applicable
Kubernetes Version
No response
Helm Chart configuration
No response
Docker Image customizations
No response
Anything else?
No response
Are you willing to submit PR?
Code of Conduct