# Buggy code
def _generate_room_entry(
    self,
    sync_result_builder,
    ignored_users,
    room_builder,
    ephemeral,
    tags,
    account_data,
    always_include=False,
):
    """Populates the `joined` and `archived` section of `sync_result_builder`
    based on the `room_builder`.

    Args:
        sync_result_builder(SyncResultBuilder)
        ignored_users(set(str)): Set of users ignored by user.
        room_builder(RoomSyncResultBuilder)
        ephemeral(list): List of new ephemeral events for room
        tags(list): List of *all* tags for room, or None if there has been
            no change.
        account_data(list): List of new account data for room
        always_include(bool): Always include this room in the sync response,
            even if empty.
    """
    newly_joined = room_builder.newly_joined
    full_state = (
        room_builder.full_state or newly_joined or sync_result_builder.full_state
    )
    events = room_builder.events

    # We want to shortcut out as early as possible.
    if not (always_include or account_data or ephemeral or full_state):
        if events == [] and tags is None:
            return

    now_token = sync_result_builder.now_token
    sync_config = sync_result_builder.sync_config

    room_id = room_builder.room_id
    since_token = room_builder.since_token
    upto_token = room_builder.upto_token

    batch = yield self._load_filtered_recents(
        room_id,
        sync_config,
        now_token=upto_token,
        since_token=since_token,
        recents=events,
        newly_joined_room=newly_joined,
    )

    if not batch and batch.limited:
        # This resulted in #5407, which is weird, so lets log! We do it
        # here as we have the maximum amount of information.
        user_id = sync_result_builder.sync_config.user.to_string()
        logger.info(
            "Issue #5407: Found limited batch with no events. user %s, room %s,"
            " sync_config %s, newly_joined %s, events %s, batch %s.",
            user_id,
            room_id,
            sync_config,
            newly_joined,
            events,
            batch,
        )

    if newly_joined:
        # debug for https://github.com/matrix-org/synapse/issues/4422
        issue4422_logger.debug(
            "Timeline events after filtering in newly-joined room %s: %r",
            room_id,
            batch,
        )

    # When we join the room (or the client requests full_state), we should
    # send down any existing tags. Usually the user won't have tags in a
    # newly joined room, unless either a) they've joined before or b) the
    # tag was added by synapse e.g. for server notice rooms.
    if full_state:
        user_id = sync_result_builder.sync_config.user.to_string()
        tags = yield self.store.get_tags_for_room(user_id, room_id)

        # If there aren't any tags, don't send the empty tags list down
        # sync
        if not tags:
            tags = None

    account_data_events = []
    if tags is not None:
        account_data_events.append({"type": "m.tag", "content": {"tags": tags}})

    for account_data_type, content in account_data.items():
        account_data_events.append({"type": account_data_type, "content": content})

    account_data_events = sync_config.filter_collection.filter_room_account_data(
        account_data_events
    )

    ephemeral = sync_config.filter_collection.filter_room_ephemeral(ephemeral)

    if not (always_include or batch or account_data_events or ephemeral or full_state):
        return

    state = yield self.compute_state_delta(
        room_id, batch, sync_config, since_token, now_token, full_state=full_state
    )

    summary = {}

    # we include a summary in room responses when we're lazy loading
    # members (as the client otherwise doesn't have enough info to form
    # the name itself).
    if sync_config.filter_collection.lazy_load_members() and (
        # we recalulate the summary:
        #   if there are membership changes in the timeline, or
        #   if membership has changed during a gappy sync, or
        #   if this is an initial sync.
        any(ev.type == EventTypes.Member for ev in batch.events)
        or (
            # XXX: this may include false positives in the form of LL
            # members which have snuck into state
            batch.limited and any(t == EventTypes.Member for (t, k) in state)
        )
        or since_token is None
    ):
        summary = yield self.compute_summary(
            room_id, sync_config, batch, state, now_token
        )

    if room_builder.rtype == "joined":
        unread_notifications = {}
        room_sync = JoinedSyncResult(
            room_id=room_id,
            timeline=batch,
            state=state,
            ephemeral=ephemeral,
            account_data=account_data_events,
            unread_notifications=unread_notifications,
            summary=summary,
        )

        if room_sync or always_include:
            notifs = yield self.unread_notifs_for_room_id(room_id, sync_config)

            if notifs is not None:
                unread_notifications["notification_count"] = notifs["notify_count"]
                unread_notifications["highlight_count"] = notifs["highlight_count"]

            sync_result_builder.joined.append(room_sync)

        if batch.limited and since_token:
            user_id = sync_result_builder.sync_config.user.to_string()
            logger.info(
                "Incremental gappy sync of %s for user %s with %d state events"
                % (room_id, user_id, len(state))
            )
    elif room_builder.rtype == "archived":
        room_sync = ArchivedSyncResult(
            room_id=room_id,
            timeline=batch,
            state=state,
            account_data=account_data_events,
        )
        if room_sync or always_include:
            sync_result_builder.archived.append(room_sync)
    else:
        raise Exception("Unrecognized rtype: %r", room_builder.rtype)


# Traceback (IndexError)
2019-06-09 19:03:46,101 - synapse.handlers.sync - 909 - INFO - GET-835 - Calculating sync response for @uelen:riot.firechicken.net between StreamToken(room_key='s707461', presence_key='26561430', typing_key='2874', receipt_key='634533', account_data_key='24909', push_rules_key='56', to_device_key='95', device_list_key='55442', groups_key='1') and StreamToken(room_key='s709258', presence_key=26599051, typing_key=57, receipt_key=636004, account_data_key=24914, push_rules_key=56, to_device_key=95, device_list_key=55442, groups_key=1)
2019-06-09 19:03:46,150 - synapse.metrics - 372 - INFO -  - Collecting gc 0
2019-06-09 19:03:46,437 - synapse.metrics - 372 - INFO -  - Collecting gc 0
2019-06-09 19:03:46,446 - synapse.handlers.sync - 1810 - INFO - GET-835 - Incremental gappy sync of !IFlHsKQHpcFgnpwgFn:matrix.org for user @uelen:riot.firechicken.net with 0 state events
2019-06-09 19:03:46,490 - synapse.handlers.sync - 1810 - INFO - GET-835 - Incremental gappy sync of !MbRaSiMIRhhxDtJENL:maunium.net for user @uelen:riot.firechicken.net with 2 state events
2019-06-09 19:03:46,493 - synapse.metrics - 372 - INFO -  - Collecting gc 0
2019-06-09 19:03:46,500 - synapse.handlers.sync - 1810 - INFO - GET-835 - Incremental gappy sync of !iNmaIQExDMeqdITdHH:matrix.org for user @uelen:riot.firechicken.net with 2 state events
2019-06-09 19:03:46,505 - synapse.handlers.sync - 1810 - INFO - GET-835 - Incremental gappy sync of !tvlbVxTSVUgJbmelND:matrix.org for user @uelen:riot.firechicken.net with 3 state events
2019-06-09 19:03:46,553 - synapse.http.server - 112 - ERROR - GET-835 - Failed handle request via 'SyncRestServlet': <SynapseRequest at 0x7f955618ce10 method='GET' uri='/_matrix/client/r0/sync?filter=0&timeout=0&since=s707461_26561430_2874_634533_24909_56_95_55442_1' clientproto='HTTP/1.0' site=8083>
Traceback (most recent call last):
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/storage/_base.py", line 527, in runWithConnection
    defer.returnValue(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1362, in returnValue
    raise _DefGen_Return(val)
twisted.internet.defer._DefGen_Return: [_EventDictReturn(event_id='$15600950391010258hrwAd:matrix.org', topological_ordering=None, stream_ordering=708773), _EventDictReturn(event_id='$15600950171010117CdspK:matrix.org', topological_ordering=None, stream_ordering=708772), _EventDictReturn(event_id='$15600949401009508lTpzl:matrix.org', topological_ordering=None, stream_ordering=708771), _EventDictReturn(event_id='$15600949261009398foetQ:matrix.org', topological_ordering=None, stream_ordering=708770), _EventDictReturn(event_id='$15600949091009307PONGY:matrix.org', topological_ordering=None, stream_ordering=708769), _EventDictReturn(event_id='$15600948911009164JkHeG:matrix.org', topological_ordering=None, stream_ordering=708768), _EventDictReturn(event_id='$15600948821009108qkrIj:matrix.org', topological_ordering=None, stream_ordering=708767), _EventDictReturn(event_id='$15600948591008929UoHxd:matrix.org', topological_ordering=None, stream_ordering=708766), _EventDictReturn(event_id='$15600948501008732joyAz:matrix.org', topological_ordering=None, stream_ordering=708765), _EventDictReturn(event_id='$15600948321008586DDtRZ:matrix.org', topological_ordering=None, stream_ordering=708764), _EventDictReturn(event_id='$15600948311008562BFdsx:matrix.org', topological_ordering=None, stream_ordering=708763), _EventDictReturn(event_id='$15600948311008555lylfW:matrix.org', topological_ordering=None, stream_ordering=708762), _EventDictReturn(event_id='$15600948051008364bsBFK:matrix.org', topological_ordering=None, stream_ordering=708761), _EventDictReturn(event_id='$15600947551008018jCiVq:matrix.org', topological_ordering=None, stream_ordering=708760), _EventDictReturn(event_id='$15600947491007978QDPLH:matrix.org', topological_ordering=None, stream_ordering=708759), _EventDictReturn(event_id='$15600947131007663SiNSd:matrix.org', topological_ordering=None, stream_ordering=708758), _EventDictReturn(event_id='$15600946391007033aolro:matrix.org', topological_ordering=None, stream_ordering=708755), _EventDictReturn(event_id='$15600946091006766ZzkSV:matrix.org', topological_ordering=None, stream_ordering=708754), _EventDictReturn(event_id='$15600945021005812lLBZU:matrix.org', topological_ordering=None, stream_ordering=708752), _EventDictReturn(event_id='$15600945001005804zAlqr:matrix.org', topological_ordering=None, stream_ordering=708751), _EventDictReturn(event_id='$15600945001005796CUSFf:matrix.org', topological_ordering=None, stream_ordering=708750)]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/storage/_base.py", line 487, in runInteraction
    defer.returnValue(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1362, in returnValue
    raise _DefGen_Return(val)
twisted.internet.defer._DefGen_Return: [_EventDictReturn(event_id='$15600950391010258hrwAd:matrix.org', topological_ordering=None, stream_ordering=708773), _EventDictReturn(event_id='$15600950171010117CdspK:matrix.org', topological_ordering=None, stream_ordering=708772), _EventDictReturn(event_id='$15600949401009508lTpzl:matrix.org', topological_ordering=None, stream_ordering=708771), _EventDictReturn(event_id='$15600949261009398foetQ:matrix.org', topological_ordering=None, stream_ordering=708770), _EventDictReturn(event_id='$15600949091009307PONGY:matrix.org', topological_ordering=None, stream_ordering=708769), _EventDictReturn(event_id='$15600948911009164JkHeG:matrix.org', topological_ordering=None, stream_ordering=708768), _EventDictReturn(event_id='$15600948821009108qkrIj:matrix.org', topological_ordering=None, stream_ordering=708767), _EventDictReturn(event_id='$15600948591008929UoHxd:matrix.org', topological_ordering=None, stream_ordering=708766), _EventDictReturn(event_id='$15600948501008732joyAz:matrix.org', topological_ordering=None, stream_ordering=708765), _EventDictReturn(event_id='$15600948321008586DDtRZ:matrix.org', topological_ordering=None, stream_ordering=708764), _EventDictReturn(event_id='$15600948311008562BFdsx:matrix.org', topological_ordering=None, stream_ordering=708763), _EventDictReturn(event_id='$15600948311008555lylfW:matrix.org', topological_ordering=None, stream_ordering=708762), _EventDictReturn(event_id='$15600948051008364bsBFK:matrix.org', topological_ordering=None, stream_ordering=708761), _EventDictReturn(event_id='$15600947551008018jCiVq:matrix.org', topological_ordering=None, stream_ordering=708760), _EventDictReturn(event_id='$15600947491007978QDPLH:matrix.org', topological_ordering=None, stream_ordering=708759), _EventDictReturn(event_id='$15600947131007663SiNSd:matrix.org', topological_ordering=None, stream_ordering=708758), _EventDictReturn(event_id='$15600946391007033aolro:matrix.org', topological_ordering=None, stream_ordering=708755), _EventDictReturn(event_id='$15600946091006766ZzkSV:matrix.org', topological_ordering=None, stream_ordering=708754), _EventDictReturn(event_id='$15600945021005812lLBZU:matrix.org', topological_ordering=None, stream_ordering=708752), _EventDictReturn(event_id='$15600945001005804zAlqr:matrix.org', topological_ordering=None, stream_ordering=708751), _EventDictReturn(event_id='$15600945001005796CUSFf:matrix.org', topological_ordering=None, stream_ordering=708750)]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/storage/stream.py", line 414, in get_room_events_stream_for_room
    defer.returnValue((ret, key))
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1362, in returnValue
    raise _DefGen_Return(val)
twisted.internet.defer._DefGen_Return: ([<FrozenEvent event_id='$15600945001005796CUSFf:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600945001005804zAlqr:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600945021005812lLBZU:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600946091006766ZzkSV:matrix.org', type='m.room.member', state_key='@freenode_heatsink:matrix.org'>, <FrozenEvent event_id='$15600946391007033aolro:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600947131007663SiNSd:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600947491007978QDPLH:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600947551008018jCiVq:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948051008364bsBFK:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948311008555lylfW:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948311008562BFdsx:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948321008586DDtRZ:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948501008732joyAz:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948591008929UoHxd:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948821009108qkrIj:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600948911009164JkHeG:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600949091009307PONGY:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600949261009398foetQ:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600949401009508lTpzl:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600950171010117CdspK:matrix.org', type='m.room.message', state_key='None'>, <FrozenEvent event_id='$15600950391010258hrwAd:matrix.org', type='m.room.message', state_key='None'>], 's708750')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 472, in _load_filtered_recents
    limited=limited or newly_joined_room
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1362, in returnValue
    raise _DefGen_Return(val)
twisted.internet.defer._DefGen_Return: TimelineBatch(prev_batch=StreamToken(room_key='s708889', presence_key=26599051, typing_key=57, receipt_key=636004, account_data_key=24914, push_rules_key=56, to_device_key=95, device_list_key=55442, groups_key=1), events=[], limited=True)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/http/server.py", line 81, in wrapped_request_handler
    yield h(self, request)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/http/server.py", line 316, in _async_render
    callback_return = yield callback(request, **kwargs)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/rest/client/v2_alpha/sync.py", line 167, in on_GET
    full_state=full_state
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 242, in wait_for_sync_for_user
    sync_config, since_token, timeout, full_state,
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 264, in _wait_for_sync_for_user
    sync_config, since_token, full_state=full_state,
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 935, in generate_sync_result
    sync_result_builder, account_data_by_room
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 1316, in _generate_sync_entry_for_rooms
    yield concurrently_execute(handle_room_entries, room_entries, 10)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/util/async_helpers.py", line 149, in _concurrently_execute_inner
    yield func(next(it))
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 1752, in _generate_room_entry
    full_state=full_state
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/home/synapse/synapse/env3/lib/python3.6/site-packages/synapse/handlers/sync.py", line 775, in compute_state_delta
    batch.events[0].event_id, state_filter=state_filter,
IndexError: list index out of range
2019-06-09 19:03:46,556 - synapse.access.http.8083 - 302 - INFO - GET-835 - 127.0.0.1 - 8083 - {@uelen:riot.firechicken.net} Processed request: 0.457sec/0.001sec (0.185sec, 0.004sec) (0.186sec/0.941sec/32) 55B 500 "GET /_matrix/client/r0/sync?filter=0&timeout=0&since=s707461_26561430_2874_634533_24909_56_95_55442_1 HTTP/1.0" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" [1 dbevts]


# Fixed code
def _generate_room_entry(
    self,
    sync_result_builder,
    ignored_users,
    room_builder,
    ephemeral,
    tags,
    account_data,
    always_include=False,
):
    """Populates the `joined` and `archived` section of `sync_result_builder`
    based on the `room_builder`.

    Args:
        sync_result_builder(SyncResultBuilder)
        ignored_users(set(str)): Set of users ignored by user.
        room_builder(RoomSyncResultBuilder)
        ephemeral(list): List of new ephemeral events for room
        tags(list): List of *all* tags for room, or None if there has been
            no change.
        account_data(list): List of new account data for room
        always_include(bool): Always include this room in the sync response,
            even if empty.
    """
    newly_joined = room_builder.newly_joined
    full_state = (
        room_builder.full_state or newly_joined or sync_result_builder.full_state
    )
    events = room_builder.events

    # We want to shortcut out as early as possible.
    if not (always_include or account_data or ephemeral or full_state):
        if events == [] and tags is None:
            return

    now_token = sync_result_builder.now_token
    sync_config = sync_result_builder.sync_config

    room_id = room_builder.room_id
    since_token = room_builder.since_token
    upto_token = room_builder.upto_token

    batch = yield self._load_filtered_recents(
        room_id,
        sync_config,
        now_token=upto_token,
        since_token=since_token,
        recents=events,
        newly_joined_room=newly_joined,
    )

    # Note: `batch` can be both empty and limited here in the case where
    # `_load_filtered_recents` can't find any events the user should see
    # (e.g. due to having ignored the sender of the last 50 events).

    if newly_joined:
        # debug for https://github.com/matrix-org/synapse/issues/4422
        issue4422_logger.debug(
            "Timeline events after filtering in newly-joined room %s: %r",
            room_id,
            batch,
        )

    # When we join the room (or the client requests full_state), we should
    # send down any existing tags. Usually the user won't have tags in a
    # newly joined room, unless either a) they've joined before or b) the
    # tag was added by synapse e.g. for server notice rooms.
    if full_state:
        user_id = sync_result_builder.sync_config.user.to_string()
        tags = yield self.store.get_tags_for_room(user_id, room_id)

        # If there aren't any tags, don't send the empty tags list down
        # sync
        if not tags:
            tags = None

    account_data_events = []
    if tags is not None:
        account_data_events.append({"type": "m.tag", "content": {"tags": tags}})

    for account_data_type, content in account_data.items():
        account_data_events.append({"type": account_data_type, "content": content})

    account_data_events = sync_config.filter_collection.filter_room_account_data(
        account_data_events
    )

    ephemeral = sync_config.filter_collection.filter_room_ephemeral(ephemeral)

    if not (always_include or batch or account_data_events or ephemeral or full_state):
        return

    state = yield self.compute_state_delta(
        room_id, batch, sync_config, since_token, now_token, full_state=full_state
    )

    summary = {}

    # we include a summary in room responses when we're lazy loading
    # members (as the client otherwise doesn't have enough info to form
    # the name itself).
    if sync_config.filter_collection.lazy_load_members() and (
        # we recalulate the summary:
        #   if there are membership changes in the timeline, or
        #   if membership has changed during a gappy sync, or
        #   if this is an initial sync.
        any(ev.type == EventTypes.Member for ev in batch.events)
        or (
            # XXX: this may include false positives in the form of LL
            # members which have snuck into state
            batch.limited and any(t == EventTypes.Member for (t, k) in state)
        )
        or since_token is None
    ):
        summary = yield self.compute_summary(
            room_id, sync_config, batch, state, now_token
        )

    if room_builder.rtype == "joined":
        unread_notifications = {}
        room_sync = JoinedSyncResult(
            room_id=room_id,
            timeline=batch,
            state=state,
            ephemeral=ephemeral,
            account_data=account_data_events,
            unread_notifications=unread_notifications,
            summary=summary,
        )

        if room_sync or always_include:
            notifs = yield self.unread_notifs_for_room_id(room_id, sync_config)

            if notifs is not None:
                unread_notifications["notification_count"] = notifs["notify_count"]
                unread_notifications["highlight_count"] = notifs["highlight_count"]

            sync_result_builder.joined.append(room_sync)

        if batch.limited and since_token:
            user_id = sync_result_builder.sync_config.user.to_string()
            logger.info(
                "Incremental gappy sync of %s for user %s with %d state events"
                % (room_id, user_id, len(state))
            )
    elif room_builder.rtype == "archived":
        room_sync = ArchivedSyncResult(
            room_id=room_id,
            timeline=batch,
            state=state,
            account_data=account_data_events,
        )
        if room_sync or always_include:
            sync_result_builder.archived.append(room_sync)
    else:
        raise Exception("Unrecognized rtype: %r", room_builder.rtype)