From 09d83f312713c8d2acc0b83f27be2e2b607a2015 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Tue, 7 Apr 2026 14:12:01 +0200 Subject: [PATCH 1/6] Fix `KNOWN_ROOM_VERSIONS.__contains__` raising TypeError for non-string keys (#19649) The Rust port of `KNOWN_ROOM_VERSIONS` (#19589) made `__contains__` strict about key types, raising `TypeError` when called with `None` instead of returning `False` like a Python dict would. This broke `/sync` for rooms with a NULL `room_version` in the database. ``` File "/home/synapse/src/synapse/handlers/sync.py", line 2628, in _get_room_changes_for_initial_sync if event.room_version_id not in KNOWN_ROOM_VERSIONS: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: argument 'key': 'NoneType' object cannot be cast as 'str' ``` --- changelog.d/19649.bugfix | 1 + rust/src/room_versions.rs | 16 +++++++-- tests/synapse_rust/test_room_versions.py | 45 ++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 changelog.d/19649.bugfix create mode 100644 tests/synapse_rust/test_room_versions.py diff --git a/changelog.d/19649.bugfix b/changelog.d/19649.bugfix new file mode 100644 index 0000000000..948dc4feac --- /dev/null +++ b/changelog.d/19649.bugfix @@ -0,0 +1 @@ +Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a NULL room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589). diff --git a/rust/src/room_versions.rs b/rust/src/room_versions.rs index c0b304e18c..fbcc32516a 100644 --- a/rust/src/room_versions.rs +++ b/rust/src/room_versions.rs @@ -600,7 +600,12 @@ impl KnownRoomVersionsMapping { Ok(()) } - fn __getitem__(&self, key: &str) -> PyResult { + fn __getitem__(&self, key: &Bound<'_, PyAny>) -> PyResult { + // We need to accept anything as the key, but we know that only strings + // are valid keys, so if it's not a string we just raise a KeyError. + let Ok(key) = key.extract::<&str>() else { + return Err(PyKeyError::new_err(key.to_string())); + }; let versions = self.versions.read().unwrap(); versions .iter() @@ -609,9 +614,14 @@ impl KnownRoomVersionsMapping { .ok_or_else(|| PyKeyError::new_err(key.to_string())) } - fn __contains__(&self, key: &str) -> PyResult { + fn __contains__(&self, key: &Bound<'_, PyAny>) -> bool { + // We need to accept anything as the key, but we know that only strings + // are valid keys, so if it's not a string we just return false. + let Ok(key) = key.extract::<&str>() else { + return false; + }; let versions = self.versions.read().unwrap(); - Ok(versions.iter().any(|v| v.identifier == key)) + versions.iter().any(|v| v.identifier == key) } fn keys(&self) -> PyResult> { diff --git a/tests/synapse_rust/test_room_versions.py b/tests/synapse_rust/test_room_versions.py new file mode 100644 index 0000000000..aff1ab2783 --- /dev/null +++ b/tests/synapse_rust/test_room_versions.py @@ -0,0 +1,45 @@ +# +# This file is licensed under the Affero General Public License (AGPL) version 3. +# +# Copyright (C) 2026 Element Creations Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# See the GNU Affero General Public License for more details: +# . + +from synapse.api.room_versions import KNOWN_ROOM_VERSIONS + +from tests import unittest + + +class KnownRoomVersionsMappingTestCase(unittest.TestCase): + """Tests for the Rust-backed KNOWN_ROOM_VERSIONS mapping.""" + + def test_contains_none(self) -> None: + """Test that `None in KNOWN_ROOM_VERSIONS` returns False + rather than raising a TypeError, matching Python dict semantics.""" + self.assertFalse(None in KNOWN_ROOM_VERSIONS) + + def test_contains_non_string(self) -> None: + """Test that non-string keys return False from __contains__.""" + self.assertFalse(42 in KNOWN_ROOM_VERSIONS) # type: ignore[comparison-overlap] + self.assertFalse(3.14 in KNOWN_ROOM_VERSIONS) # type: ignore[comparison-overlap] + self.assertFalse([] in KNOWN_ROOM_VERSIONS) # type: ignore[comparison-overlap] + + def test_contains_known_version(self) -> None: + self.assertTrue("1" in KNOWN_ROOM_VERSIONS) + + def test_contains_unknown_version(self) -> None: + self.assertFalse("unknown" in KNOWN_ROOM_VERSIONS) + + def test_getitem_non_string_raises_key_error(self) -> None: + """Test that KNOWN_ROOM_VERSIONS[non_string] raises KeyError, + not TypeError, matching Python dict semantics.""" + with self.assertRaises(KeyError): + KNOWN_ROOM_VERSIONS[42] # type: ignore[index] + with self.assertRaises(KeyError): + KNOWN_ROOM_VERSIONS[None] # type: ignore[index] From 77b329a913cb22537164e913b4d05515d0622f42 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Tue, 7 Apr 2026 14:15:50 +0200 Subject: [PATCH 2/6] 1.151.0 --- CHANGES.md | 9 +++++++++ changelog.d/19649.bugfix | 1 - debian/changelog | 6 ++++++ pyproject.toml | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) delete mode 100644 changelog.d/19649.bugfix diff --git a/CHANGES.md b/CHANGES.md index bcf66142f9..3315dd9ee5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,12 @@ +# Synapse 1.151.0 (2026-04-07) + +## Bugfixes + +- Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a `NULL` room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589). ([\#19649](https://github.com/element-hq/synapse/issues/19649)) + + + + # Synapse 1.151.0rc1 (2026-03-31) ## Features diff --git a/changelog.d/19649.bugfix b/changelog.d/19649.bugfix deleted file mode 100644 index 948dc4feac..0000000000 --- a/changelog.d/19649.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a NULL room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589). diff --git a/debian/changelog b/debian/changelog index 36fa0e5140..f3dc1eb0c2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +matrix-synapse-py3 (1.151.0) stable; urgency=medium + + * New synapse release 1.151.0. + + -- Synapse Packaging team Tue, 07 Apr 2026 12:15:10 +0000 + matrix-synapse-py3 (1.151.0~rc1) stable; urgency=medium * New synapse release 1.151.0rc1. diff --git a/pyproject.toml b/pyproject.toml index 27cdbcb671..5fa7dade52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "matrix-synapse" -version = "1.151.0rc1" +version = "1.151.0" description = "Homeserver for the Matrix decentralised comms protocol" readme = "README.rst" authors = [ From cee606e590c72a91acd529d63cfbd79db800b2a8 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Tue, 7 Apr 2026 14:21:23 +0200 Subject: [PATCH 3/6] Mention the rc in the bug fix in the changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 3315dd9ee5..e76497cf99 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## Bugfixes -- Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a `NULL` room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589). ([\#19649](https://github.com/element-hq/synapse/issues/19649)) +- Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a `NULL` room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589). ([\#19649](https://github.com/element-hq/synapse/issues/19649)) as part of v1.151.0rc1. From 4ea109aa5cdeb52ab63d619f676ffe490fc86557 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Tue, 7 Apr 2026 14:29:49 +0200 Subject: [PATCH 4/6] Fix the changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index e76497cf99..c6e06aad49 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## Bugfixes -- Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a `NULL` room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589). ([\#19649](https://github.com/element-hq/synapse/issues/19649)) as part of v1.151.0rc1. +- Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a `NULL` room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589) as part of v1.151.0rc1. ([\#19649](https://github.com/element-hq/synapse/issues/19649)) From 15662db09559fbba4e307182a4f841f24c1a17b8 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Wed, 8 Apr 2026 10:14:58 -0500 Subject: [PATCH 5/6] Fix Docker image link typo in worker docs (#19645) Fix https://github.com/element-hq/synapse/issues/19521 --- changelog.d/19645.doc | 1 + docs/workers.md | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 changelog.d/19645.doc diff --git a/changelog.d/19645.doc b/changelog.d/19645.doc new file mode 100644 index 0000000000..e46e048952 --- /dev/null +++ b/changelog.d/19645.doc @@ -0,0 +1 @@ +Fix Docker image link typo in worker docs. diff --git a/docs/workers.md b/docs/workers.md index c2aef33e16..201ef8f854 100644 --- a/docs/workers.md +++ b/docs/workers.md @@ -60,10 +60,10 @@ virtualenv, these can be installed with: pip install "matrix-synapse[redis]" ``` -Note that these dependencies are included when synapse is installed with `pip -install matrix-synapse[all]`. They are also included in the debian packages from -`packages.matrix.org` and in the docker images at -https://hub.docker.com/r/ectorim/synapse/. +Note that these dependencies are included when Synapse is installed with `pip install +matrix-synapse[all]`. They are also included in the [Debian +packages](setup/installation.md#debianubuntu) and in the [Docker +images](setup/installation.md#docker-images-and-ansible-playbooks). To make effective use of the workers, you will need to configure an HTTP reverse-proxy such as nginx or haproxy, which will direct incoming requests to From 35b55e962aa0bed3b2da5a3c12e3783ddf7604ca Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Wed, 8 Apr 2026 10:47:13 -0500 Subject: [PATCH 6/6] Advertise MSC4445 sync timeline order (#19642) Synapse uses topological ordering for initial sync (first time a room is sent down `/sync`), https://github.com/element-hq/synapse/blob/2e9b8202f0a1a8ceba9f02bb5ec227498d51dcbd/synapse/handlers/sync.py#L768-L805 --- changelog.d/19642.feature | 1 + synapse/rest/client/versions.py | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 changelog.d/19642.feature diff --git a/changelog.d/19642.feature b/changelog.d/19642.feature new file mode 100644 index 0000000000..dfb8e5f5a3 --- /dev/null +++ b/changelog.d/19642.feature @@ -0,0 +1 @@ +Advertise [MSC4445](https://github.com/matrix-org/matrix-spec-proposals/pull/4445) sync timeline order in `unstable_features`. diff --git a/synapse/rest/client/versions.py b/synapse/rest/client/versions.py index 7bf4b12e8b..bb1711f2cf 100644 --- a/synapse/rest/client/versions.py +++ b/synapse/rest/client/versions.py @@ -206,6 +206,8 @@ class VersionsRestServlet(RestServlet): "org.matrix.msc4354": self.config.experimental.msc4354_enabled, # MSC4380: Invite blocking "org.matrix.msc4380.stable": True, + # MSC4445: Sync timeline order + "org.matrix.msc4445.initial_sync_timeline_topological_ordering": True, }, }, )