From 2d19bcd74889d7813ef5ca2c2d85db0b13fa3707 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Thu, 7 May 2026 15:20:38 -0500 Subject: [PATCH 1/4] fix _rebuild_event_after_third_party_rules() to be creation event/room V12 compliant --- synapse/handlers/message.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index 0687c9fa790..5ab9e91c0de 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -2376,7 +2376,15 @@ async def _rebuild_event_after_third_party_rules( original_event.room_version, third_party_result ) self.validator.validate_builder(builder) - assert builder.room_id is not None + + # The room_id should only be None for creation events using msc4291 + # rooms(version "12" and newer) + if not ( + builder.room_version.msc4291_room_ids_as_hashes + and builder.type == EventTypes.Create + ): + assert builder.room_id is not None + except SynapseError as e: raise Exception( "Third party rules module created an invalid event: " + e.msg, @@ -2411,12 +2419,21 @@ async def _rebuild_event_after_third_party_rules( for k, v in original_event.internal_metadata.get_dict().items(): setattr(builder.internal_metadata, k, v) - # modules can send new state events, so we re-calculate the auth events just in - # case. - prev_event_ids = await self.store.get_prev_events_for_room(builder.room_id) + # Creation events using msc4291 rooms will not have a room_id, and will + # also not have prev_events nor prev_state_events. + # This was asserted above, so makes an acceptable sign that room_id can not be + # None here(which makes mypy happy) but if it is then the lists should be empty. + prev_event_ids = [] + if builder.room_id is not None: + # modules can send new state events, so we re-calculate the auth events just + # in case. + prev_event_ids = await self.store.get_prev_events_for_room(builder.room_id) prev_state_events = None - if original_event.room_version.msc4242_state_dags: + if ( + original_event.room_version.msc4242_state_dags + and builder.room_id is not None + ): prev_state_events = list( await self.store.get_state_dag_extremities(builder.room_id) ) From 2e4b2ee2a21ea36868ef34ab7cfd854bd6e1ca90 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Thu, 7 May 2026 15:21:52 -0500 Subject: [PATCH 2/4] [revert] how to test this --- tests/rest/client/test_third_party_rules.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rest/client/test_third_party_rules.py b/tests/rest/client/test_third_party_rules.py index 1709b27f67c..95afc5e82b6 100644 --- a/tests/rest/client/test_third_party_rules.py +++ b/tests/rest/client/test_third_party_rules.py @@ -382,7 +382,8 @@ def test_send_event(self) -> None: "third_party_event_rules": { "module": __name__ + ".LegacyChangeEvents", "config": {}, - } + }, + "default_room_version": "12", } ) def test_legacy_check_event_allowed(self) -> None: From d802d85f2167f942932b87d82cf4f9b7ba06353a Mon Sep 17 00:00:00 2001 From: Jason Little Date: Mon, 11 May 2026 07:41:43 -0500 Subject: [PATCH 3/4] changelog --- changelog.d/19768.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/19768.misc diff --git a/changelog.d/19768.misc b/changelog.d/19768.misc new file mode 100644 index 00000000000..8314491ced0 --- /dev/null +++ b/changelog.d/19768.misc @@ -0,0 +1 @@ +Allow the Third Party Rules `check_event_allowed()` callback to work with [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291) rooms. Contributed by @famedly. From cc29279bc9201b20a9a3c49292ae407710e6c4d4 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Thu, 25 Jun 2026 10:19:35 -0500 Subject: [PATCH 4/4] apply some feedback and rearrange a few comments --- synapse/handlers/message.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index 5ab9e91c0de..17d6c49ce3d 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -2377,14 +2377,6 @@ async def _rebuild_event_after_third_party_rules( ) self.validator.validate_builder(builder) - # The room_id should only be None for creation events using msc4291 - # rooms(version "12" and newer) - if not ( - builder.room_version.msc4291_room_ids_as_hashes - and builder.type == EventTypes.Create - ): - assert builder.room_id is not None - except SynapseError as e: raise Exception( "Third party rules module created an invalid event: " + e.msg, @@ -2420,20 +2412,19 @@ async def _rebuild_event_after_third_party_rules( setattr(builder.internal_metadata, k, v) # Creation events using msc4291 rooms will not have a room_id, and will - # also not have prev_events nor prev_state_events. - # This was asserted above, so makes an acceptable sign that room_id can not be - # None here(which makes mypy happy) but if it is then the lists should be empty. + # also not have prev_events nor prev_state_events(below). This makes mypy happy. prev_event_ids = [] if builder.room_id is not None: - # modules can send new state events, so we re-calculate the auth events just - # in case. prev_event_ids = await self.store.get_prev_events_for_room(builder.room_id) prev_state_events = None if ( original_event.room_version.msc4242_state_dags + and builder.type != EventTypes.Create and builder.room_id is not None ): + # modules can send new state events, so we re-calculate the auth events just + # in case. prev_state_events = list( await self.store.get_state_dag_extremities(builder.room_id) )