diff --git a/changelog.d/19464.bugfix b/changelog.d/19464.bugfix new file mode 100644 index 00000000000..147e0b6ec79 --- /dev/null +++ b/changelog.d/19464.bugfix @@ -0,0 +1 @@ +Fix `/sync` `timeline` state duplicated in `state` when lazy-loading. diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py index a32748c2a9c..a56ab4be3b7 100644 --- a/synapse/handlers/sync.py +++ b/synapse/handlers/sync.py @@ -1046,6 +1046,13 @@ async def compute_state_delta( if event.sender not in first_event_by_sender_map: first_event_by_sender_map[event.sender] = event + # Add to the `timeline_state` first before we check whether members + # are in the `timeline` just below. Otherwise, we will end up with + # extra things in `state` that should have only been in the + # `timeline`. + if event.is_state(): + timeline_state[(event.type, event.state_key)] = event.event_id + # When using `state_after`, there is no special treatment with # regards to state also being in the `timeline`. Always fetch # relevant membership regardless of whether the state event is in @@ -1061,9 +1068,6 @@ async def compute_state_delta( members_to_fetch.add(event.sender) # FIXME: we also care about invite targets etc. - if event.is_state(): - timeline_state[(event.type, event.state_key)] = event.event_id - else: timeline_state = { (event.type, event.state_key): event.event_id