A @task.stub task that a coordinator runs in a Lang-SDK runtime (Go, Java, TypeScript) never runs the task callbacks declared on it in the Python Dag, such as on_failure_callback and on_success_callback. Callbacks run only inside the Python task runner (_run_task_state_change_callbacks in task-sdk/src/airflow/sdk/execution_time/task_runner.py). The Lang-SDK runtime cannot run them, and neither the supervisor nor the Execution API sends a callback request when such a task finishes. The only exception is the scheduler's state-mismatch path ("killed externally?"), which does send a callback request to the Dag processor.
Proposal: when a coordinator task reaches a final state, request its task callbacks so the Dag processor runs them from the Python Dag file, as it already does for a task that was killed externally.
Drafted with Claude Code (Opus 5.5).
A
@task.stubtask that a coordinator runs in a Lang-SDK runtime (Go, Java, TypeScript) never runs the task callbacks declared on it in the Python Dag, such ason_failure_callbackandon_success_callback. Callbacks run only inside the Python task runner (_run_task_state_change_callbacksintask-sdk/src/airflow/sdk/execution_time/task_runner.py). The Lang-SDK runtime cannot run them, and neither the supervisor nor the Execution API sends a callback request when such a task finishes. The only exception is the scheduler's state-mismatch path ("killed externally?"), which does send a callback request to the Dag processor.Proposal: when a coordinator task reaches a final state, request its task callbacks so the Dag processor runs them from the Python Dag file, as it already does for a task that was killed externally.
Drafted with Claude Code (Opus 5.5).