This is an automated email from the ASF dual-hosted git repository.

shahar1 pushed a commit to branch v3-4-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-4-test by this push:
     new ad9973e7172 [v3-4-test] Fix XComs of task-end trigger events being 
JSON-encoded twice (#76596) (#76989)
ad9973e7172 is described below

commit ad9973e7172a943b6606adebdf706769aab66a8c
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Nov 12 21:36:05 2026 +0000

    [v3-4-test] Fix XComs of task-end trigger events being JSON-encoded twice 
(#76596) (#76989)
    
    (cherry picked from commit 1c870b3478d63680151b0170f6427be8756a11ce)
    
    Co-authored-by: raphaelauv <[email protected]>
---
 airflow-core/src/airflow/models/trigger.py     | 10 +++++++++-
 airflow-core/tests/unit/models/test_trigger.py |  9 ++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/airflow-core/src/airflow/models/trigger.py 
b/airflow-core/src/airflow/models/trigger.py
index 656a2a474a1..7a504ff7f14 100644
--- a/airflow-core/src/airflow/models/trigger.py
+++ b/airflow-core/src/airflow/models/trigger.py
@@ -745,9 +745,17 @@ def _(event: BaseTaskEndEvent, *, task_instance: 
TaskInstance, session: Session)
 
     def _push_xcoms_if_necessary() -> None:
         """Pushes XComs to the database if they are provided."""
+        from airflow.models.xcom import XComModel
+
         if event.xcoms and callback_type != TaskInstanceState.UP_FOR_RETRY:
             for key, value in event.xcoms.items():
-                task_instance.xcom_push(key=key, value=value)
+                XComModel.set_for_attempt(
+                    task_instance_id=task_instance.id,
+                    key=key,
+                    value=value,
+                    serialize=False,
+                    session=session,
+                )
 
     # Send the callback before mutating task state so it reflects the 
retry-vs-terminal
     # decision derived above.
diff --git a/airflow-core/tests/unit/models/test_trigger.py 
b/airflow-core/tests/unit/models/test_trigger.py
index ff12adf0f37..43923fa21ab 100644
--- a/airflow-core/tests/unit/models/test_trigger.py
+++ b/airflow-core/tests/unit/models/test_trigger.py
@@ -672,7 +672,9 @@ def test_submit_event_task_end(mock_utcnow, session, 
create_task_instance, event
     # now, for each type, submit event
     # verify that (1) task ends in right state and (2) xcom is pushed
     Trigger.submit_event(
-        trigger.id, event_cls(xcoms={"return_value": "xcomret", "a": "b", "c": 
"d"}), session=session
+        trigger.id,
+        event_cls(xcoms={"return_value": "xcomret", "a": "b", "c": {"d": [1, 
2]}}),
+        session=session,
     )
     # commit changes made by submit event and expire all cache to read from db.
     session.flush()
@@ -683,10 +685,7 @@ def test_submit_event_task_end(mock_utcnow, session, 
create_task_instance, event
     assert ti.end_date == now
     assert ti.duration is not None
     actual_xcoms = {x.key: x.value for x in get_xcoms(ti)}
-    expected_xcoms = {}
-    for k, v in {"return_value": "xcomret", "a": "b", "c": "d"}.items():
-        expected_xcoms[k] = json.dumps(v)
-    assert actual_xcoms == expected_xcoms
+    assert actual_xcoms == {"return_value": "xcomret", "a": "b", "c": {"d": 
[1, 2]}}
 
 
 @patch("airflow.callbacks.database_callback_sink.DatabaseCallbackSink.send")

Reply via email to