kaxil commented on code in PR #75423:
URL: https://github.com/apache/airflow/pull/75423#discussion_r4354770030


##########
airflow-core/newsfragments/75423.bugfix.rst:
##########
@@ -0,0 +1 @@
+A task that runs entirely in the triggerer (``start_from_trigger=True``) now 
records its rendered template fields, so the Rendered Templates tab shows them 
instead of staying empty for the whole run.

Review Comment:
   Can you drop this? airflow-core only takes `significant` newsfragments now, 
for changes users must read before upgrading, and never for an ordinary bug fix 
(see `contributing-docs/18_contribution_workflow.rst`).



##########
airflow-core/src/airflow/jobs/triggerer_job_runner.py:
##########
@@ -1467,6 +1475,32 @@ def create_runtime_ti(
             ),
         )
 
+    async def record_rendered_fields(self, runtime_ti: RuntimeTaskInstance, 
context: Context) -> None:
+        """
+        Record the rendered template fields of a task that starts from the 
triggerer.
+
+        Such a task never starts in a worker, so nothing else records them and 
the Rendered
+        Templates tab stays empty for the whole run. Rendering is best effort: 
a task whose
+        fields cannot be rendered here still has a trigger to run.
+        """
+        # Reused rather than reimplemented so core cannot drift from the 
redaction the worker applies.
+        from airflow.sdk.execution_time.task_runner import 
_serialize_rendered_fields  # noqa: SDK001
+
+        try:
+            context["task"] = runtime_ti.task
+            runtime_ti.render_templates(context=context, 
jinja_env=runtime_ti.task.dag.get_template_env())

Review Comment:
   In production this never gets past this line. `create_runtime_ti` builds the 
task with `DagSerialization.from_dict(...).get_task(...)`, so `runtime_ti.task` 
is a core `SerializedBaseOperator` and `.dag` is a `SerializedDAG`, and neither 
has `get_template_env` or `render_template_fields`. The `AttributeError` is 
caught below, so every start-from-trigger task logs "Failed to render template 
fields" with a traceback and nothing is sent. I ran `record_rendered_fields` on 
a task built that way: `asend` was never awaited and the log had 
`'SerializedDAG' object has no attribute 'get_template_env'`.
   
   Adding those methods to the serialized classes wouldn't get there either. 
Rendering an operator's fields needs things the serialized Dag doesn't carry 
(`user_defined_macros`, `user_defined_filters`, `template_searchpath` for 
`template_ext` files), and the triggerer doesn't load Dag bundles. #53071 had 
the triggerer load the Dag to render task fields and was reverted in #55037 for 
that reason.
   
   What the triggerer can render is what it already renders: `BaseTrigger` 
renders the operator template fields passed through 
`start_trigger_args.trigger_kwargs` (`target_time` for `DateTimeSensorAsync`, 
the case in the issue). Recording those after 
`trigger.render_template_fields(context)` would work without the Dag file, 
though it only covers the fields the trigger receives.



##########
airflow-core/tests/unit/jobs/test_triggerer_job.py:
##########
@@ -4007,3 +4007,65 @@ async def fake_run():
         log.get("event") == "Trigger fired event payload" and 
log.get("result") == TriggerEvent(payload)
         for log in debug_logs
     ), "Full event payload must be logged at DEBUG level"
+
+
+class _TemplatedOperator(BaseOperator):
+    """Minimal operator with a templated field, for the start-from-trigger 
rendering tests."""
+
+    template_fields = ("greeting",)
+
+    def __init__(self, *, greeting: str, **kwargs):
+        super().__init__(**kwargs)
+        self.greeting = greeting
+
+    def execute(self, context):
+        raise AssertionError("start_from_trigger tasks never execute in a 
worker")
+
+
+def _runtime_ti_with_templated_task(greeting: str):
+    from airflow.sdk.execution_time.task_runner import RuntimeTaskInstance
+
+    with DAG("rendered_fields_dag", schedule=None, 
start_date=timezone.datetime(2026, 1, 1)):
+        task = _TemplatedOperator(task_id="templated", greeting=greeting)
+
+    return RuntimeTaskInstance.model_construct(

Review Comment:
   These tests hand `model_construct` an SDK `BaseOperator`, but production 
builds the TI through `TriggerRunner.create_runtime_ti(ti, 
DagSerialization.to_dict(dag), dag_run_data)`, which is why they pass while the 
real path raises. Building it that way would have caught the problem above. The 
new `SetRenderedFields` branch in `_handle_request` also has no test.



-- 
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