Repository: matrix-org/synapse

Issue:
Error: Event has no state groups
Unclear severity. This is on the develop branch as of writing. Happens to several events in different rooms at different times (not a pattern).

```
er - 2018-07-25 06:20:39,274 - synapse.storage.events - 422 - INFO - Calculating state delta for room !redacted:matrix.org
homeserver - 2018-07-25 06:20:39,275 - synapse.util.async - 250 - INFO - Releasing linearizer lock 'fed_room_pdu' for key '!redacted:matrix.org'
homeserver - 2018-07-25 06:20:39,275 - synapse.federation.federation_server - 194 - ERROR - Failed to handle PDU $redacted:matrix.org: Traceback (most recent call last):
--- <exception caught here> ---
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/federation/federation_server.py", line 183, in process_pdus_for_room
    transaction.origin, pdu
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/federation/federation_server.py", line 605, in _handle_received_pdu
    origin, pdu, get_missing=True, sent_to_us_directly=True,
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/federation.py", line 213, in on_receive_pdu
    origin, pdu, prevs, min_depth
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/federation.py", line 366, in _get_missing_events_for_pdu
    get_missing=False
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/federation.py", line 290, in on_receive_pdu
    auth_chain=auth_chain,
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/federation.py", line 444, in _process_received_pdu
    yield self._handle_new_events(origin, event_infos)
  File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/federation.py", line 1525, in _handle_new_events
    backfilled=backfilled,
twisted.internet.defer.FirstError: FirstError[#0, [Failure instance: Traceback: <type 'exceptions.Exception'>: Context for new extremity event $redacted:matrix.org has no state group
/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py:1418:_inlineCallbacks
/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/events.py:432:_persist_events
/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py:1613:unwindGenerator
/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py:1529:_cancellableInlineCallbacks
--- <exception caught here> ---
/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/events.py:149:handle_queue_loop
/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/events.py:293:persisting_queue
/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/events.py:188:f
/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/events.py:432:_persist_events
/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py:1418:_inlineCallbacks
/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/events.py:581:_get_new_state_after_events
]]
homeserver - 2018-07-25 06:20:39,283 - synapse.util.logcontext - 273 - WARNING - Expected logging context persist_events@7fccd36db488 has been lost
```


Discussion:

Resolving patch:
diff --git a/synapse/storage/events.py b/synapse/storage/events.py
--- a/synapse/storage/events.py
+++ b/synapse/storage/events.py
@@ -575,11 +575,13 @@ def _get_new_state_after_events(self, room_id, events_context, old_latest_event_
 
         for ev, ctx in events_context:
             if ctx.state_group is None:
-                # I don't think this can happen, but let's double-check
-                raise Exception(
-                    "Context for new extremity event %s has no state "
-                    "group" % (ev.event_id, ),
-                )
+                # This should only happen for outlier events.
+                if not ev.internal_metadata.is_outlier():
+                    raise Exception(
+                        "Context for new event %s has no state "
+                        "group" % (ev.event_id, ),
+                    )
+                continue
 
             if ctx.state_group in state_groups_map:
                 continue
@@ -607,7 +609,7 @@ def _get_new_state_after_events(self, room_id, events_context, old_latest_event_
         for event_id in new_latest_event_ids:
             # First search in the list of new events we're adding.
             for ev, ctx in events_context:
-                if event_id == ev.event_id:
+                if event_id == ev.event_id and ctx.state_group is not None:
                     event_id_to_state_group[event_id] = ctx.state_group
                     break
             else:


Test patch: