matrix-org / matrix-org/matrix-js-sdk
events are processed in wrong order, cannot chat anymore
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.2k
- Forks
- 704
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 40
Description
When somebody kicks me from a room, but invites me shortly after without my client making a sync in between (because the chat app was closed), the leave and invite event is processed in the wrong order.
The result of /sync looks fine, the `origin_server_ts` of the invite is later than the one of the leave-Event. But when listening to `client.on('event', ...)`, the invite Event comes first and the leave-Event second. This leads to a wrong state in the (persistent) store. Because of this, the app thinks the user is not in the room anymore and won't receive any new messages. The new state is "invite", but the user cannot accept the invittation, since it is not displayed.
Here is the result of `/sync`
/sync result
```json
{
"next_batch": "s127655_2818331_4835_288127_209897_85_169_14999_0",
"presence": {
"events": [
{
"type": "m.presence",
"sender": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"content": {
"presence": "online",
"last_active_ago": 17,
"currently_active": true
}
}
]
},
"device_lists": {
"left": [
"@ctbot:chat.krz.tools"
]
},
"device_one_time_keys_count": {
"signed_curve25519": 0
},
"org.matrix.msc2732.device_unused_fallback_key_types": [],
"device_unused_fallback_key_types": [],
"rooms": {
"invite": {
"!sQgeWUrcqXvxvzkUqw:chat.krz.tools": {
"invite_state": {
"events": [
{
"type": "m.room.avatar",
"state_key": "",
"content": {
"url": ""
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.canonical_alias",
"state_key": "",
"content": {
"alias": "#ctg_4b1a00f5-7753-469f-bf95-6bb3b7c1414d:chat.krz.tools"
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.create",
"state_key": "",
"content": {
"room_version": "9",
"creator": "@ctbot:chat.krz.tools"
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.join_rules",
"state_key": "",
"content": {
"join_rule": "invite"
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.name",
"state_key": "",
"content": {
"name": "Chattest"
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.topic",
"state_key": "",
"content": {
"topic": "Gruppen-Chat einer Gruppe in testsilas.krz.tools"
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.member",
"state_key": "@ctbot:chat.krz.tools",
"content": {
"membership": "join"
},
"sender": "@ctbot:chat.krz.tools"
},
{
"type": "m.room.member",
"sender": "@ctbot:chat.krz.tools",
"content": {
"membership": "invite",
"displayname": "Admin Admin"
},
"state_key": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"origin_server_ts": 1671178716243,
"unsigned": {
"replaces_state": "$LbfQGkLijKPasqYizadgfKnvLW_OKYK4izrqDLegduU",
"prev_content": {
"reason": null,
"membership": "leave"
},
"prev_sender": "@ctbot:chat.krz.tools",
"age": 41096
},
"event_id": "$elHhtOnT4Xy9mdNaHeJzVu5nVhKnRbjDEiFpN8BxBrc"
}
]
}
}
},
"leave": {
"!sQgeWUrcqXvxvzkUqw:chat.krz.tools": {
"timeline": {
"events": [
{
"type": "m.room.member",
"sender": "@ctbot:chat.krz.tools",
"content": {
"reason": null,
"membership": "leave"
},
"state_key": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"origin_server_ts": 1671178710797,
"unsigned": {
"replaces_state": "$pTOIJv3ViDwR7QyzOCLQatCwUyv5fQpNYSOaDIHXcdI",
"prev_content": {
"membership": "join",
"displayname": "Admin Admin"
},
"prev_sender": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"age": 46542
},
"event_id": "$LbfQGkLijKPasqYizadgfKnvLW_OKYK4izrqDLegduU"
}
],
"prev_batch": "s127652_2818310_4829_288126_209897_85_169_14999_0",
"limited": false
},
"state": {
"events": []
},
"account_data": {
"events": []
}
}
}
}
}
```
And the Events from `client.on('event', ...)`:
Invite Event
```json
{
"type": "m.room.member",
"sender": "@ctbot:chat.krz.tools",
"content": {
"membership": "invite",
"displayname": "Admin Admin"
},
"state_key": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"origin_server_ts": 1671178716243,
"unsigned": {
"replaces_state": "$LbfQGkLijKPasqYizadgfKnvLW_OKYK4izrqDLegduU",
"prev_content": {
"reason": null,
"membership": "leave"
},
"prev_sender": "@ctbot:chat.krz.tools",
"age": 41096
},
"event_id": "$elHhtOnT4Xy9mdNaHeJzVu5nVhKnRbjDEiFpN8BxBrc",
"room_id": "!sQgeWUrcqXvxvzkUqw:chat.krz.tools"
}
```
Leave Event
```json
{
"type": "m.room.member",
"sender": "@ctbot:chat.krz.tools",
"content": {
"reason": null,
"membership": "leave",
"displayname": "Admin Admin"
},
"state_key": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"origin_server_ts": 1671178710797,
"unsigned": {
"replaces_state": "$pTOIJv3ViDwR7QyzOCLQatCwUyv5fQpNYSOaDIHXcdI",
"prev_content": {
"membership": "join",
"displayname": "Admin Admin"
},
"prev_sender": "@ct_a18c34c2-ea65-4359-956e-b4c237c96e47:chat.krz.tools",
"age": 46542
},
"event_id": "$LbfQGkLijKPasqYizadgfKnvLW_OKYK4izrqDLegduU",
"room_id": "!sQgeWUrcqXvxvzkUqw:chat.krz.tools"
}
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the client.on('event', ...) dispatch path and the /sync handling that emits room membership events. Compare the invite and leave event ordering using the supplied timestamps and event IDs, then verify that the persistent store ends in the invited state and the invitation can be displayed and accepted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100