1fanwang commented on issue #70953: URL: https://github.com/apache/airflow/issues/70953#issuecomment-5188893409
Verified [Read HITLOperator subject/body into the summary lazily](https://github.com/apache/airflow/pull/70345) on `standard 1.17.0rc1`. Works as intended. Airflow 3.3.0, two identical virtualenvs: one with the RC providers, one with the previous stable release. Same Dag, same command, run through the real task runner. RPC is stubbed, and the stub asserts the value that actually reaches it. An `ApprovalOperator` with templated `subject` and `body`, plus a listener reading `ti.task.hitl_summary` in `on_task_instance_running`. Nothing about the operator is stubbed. The task parks in `AWAITING_INPUT`, a response is recorded through the same path the HITL REST API uses, and the task resumes. ```bash # standard 1.17.0rc1, responder drives the human side of the same run AIRFLOW_HOME=$PWD/airflow_home \ AIRFLOW__CORE__DAGS_FOLDER=$PWD/dags_e2e/rc_70345_hitl_summary \ .venv/bin/airflow dags test rc_70345_hitl_summary & AIRFLOW_HOME=$PWD/airflow_home \ .venv/bin/python hitl_responder.py rc_70345_hitl_summary approve_deploy Approve # standard 1.16.0, same Dag, same responder AIRFLOW_HOME=$PWD/airflow_home_prev \ AIRFLOW__CORE__DAGS_FOLDER=$PWD/dags_e2e/rc_70345_hitl_summary \ .venv-prev/bin/airflow dags test rc_70345_hitl_summary & AIRFLOW_HOME=$PWD/airflow_home_prev \ .venv-prev/bin/python hitl_responder.py rc_70345_hitl_summary approve_deploy Approve ``` ``` # standard 1.17.0rc1, Dag run: what the listener was handed LISTENER_SAW_SUMMARY subject='Approve deploy to prod?' body='Release 2026.8.1 is ready for prod.' RC_CHECK_OK listener saw the RENDERED subject/body [info] Pausing task as AWAITING_INPUT. [task] dag_id=rc_70345_hitl_summary task_id=approve_deploy loc=task_runner.py:1491 [info] Task instance state updated ... new_state=success DagRun Finished: dag_id=rc_70345_hitl_summary ... state=success # standard 1.17.0rc1, responder acting as the human on that same run HITL_REQUEST_SEEN_BY_HUMAN subject='Approve deploy to prod?' body='Release 2026.8.1 is ready for prod.' HUMAN_RESPONDS chosen_options=['Approve'] RESPONSE_RECORDED task resumed # standard 1.16.0, same Dag, same responder LISTENER_SAW_SUMMARY subject='Approve deploy to {{ params.env }}?' body='Release {{ params.release }} is ready for {{ params.env }}.' AssertionError: subject is un-rendered Jinja: 'Approve deploy to {{ params.env }}?' [error] error calling listener (x2) ``` To be precise about the scope: the stored HITL request is rendered on both versions, so the human sees the right text either way. What changes is `ti.task.hitl_summary`, which on 1.16.0 hands a listener the raw Jinja. The task reaches `success` on both because listener exceptions are logged and swallowed, so the evidence is the listener's own output plus the `error calling listener` count, 2 on 1.16.0 and 0 on the RC. One non-back-compat note, not a blocker. `hitl_summary` is now a property with no setter, so a subclass that extended it in `__init__` on 1.16.0 now has its entry silently dropped rather than raising: ```python class MyApproval(ApprovalOperator): def __init__(self, **kw): super().__init__(**kw) self.hitl_summary["team"] = "platform" ``` ``` # standard 1.17.0rc1 hitl_summary["team"] present? False # standard 1.16.0 hitl_summary["team"] present? True ``` The replacement is `_hitl_summary_extra`, which is private, so a subclass currently has no public way to extend the summary. -- 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]
