# Buggy code
async def notify_device_update(self, user_id, device_ids):
    """Notify that a user's device(s) has changed. Pokes the notifier, and
    remote servers if the user is local.
    """
    users_who_share_room = await self.store.get_users_who_share_room_with_user(user_id)

    hosts = set()
    if self.hs.is_mine_id(user_id):
        hosts.update(get_domain_from_id(u) for u in users_who_share_room)
        hosts.discard(self.server_name)

    set_tag("target_hosts", hosts)

    position = await self.store.add_device_change_to_streams(
        user_id, device_ids, list(hosts)
    )

    for device_id in device_ids:
        logger.debug(
            "Notifying about update %r/%r, ID: %r", user_id, device_id, position
        )

    room_ids = await self.store.get_rooms_for_user(user_id)

    # specify the user ID too since the user should always get their own device list
    # updates, even if they aren't in any rooms.
    self.notifier.on_new_event(
        "device_list_key", position, users=[user_id], rooms=room_ids
    )

    if hosts:
        logger.info("Sending device list update notif for %r to: %r", user_id, hosts)
        for host in hosts:
            self.federation_sender.send_device_messages(host)
            log_kv({"message": "sent device update to host", "host": host})


# Traceback (TypeError)
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/synapse/notifier.py", line 304, in on_new_event
user_stream.notify(stream_key, new_token, time_now_ms)
File "/usr/lib/python3/dist-packages/synapse/notifier.py", line 104, in notify
self.current_token = self.current_token.copy_and_advance(stream_key, stream_id)
File "/usr/lib/python3/dist-packages/synapse/types.py", line 401, in copy_and_advance
new_id = int(getattr(new_token, key))
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

# Fixed code
async def notify_device_update(self, user_id, device_ids):
    """Notify that a user's device(s) has changed. Pokes the notifier, and
    remote servers if the user is local.
    """
    if not device_ids:
        # No changes to notify about, so this is a no-op.
        return

    users_who_share_room = await self.store.get_users_who_share_room_with_user(user_id)

    hosts = set()
    if self.hs.is_mine_id(user_id):
        hosts.update(get_domain_from_id(u) for u in users_who_share_room)
        hosts.discard(self.server_name)

    set_tag("target_hosts", hosts)

    position = await self.store.add_device_change_to_streams(
        user_id, device_ids, list(hosts)
    )

    if not position:
        # This should only happen if there are no updates, so we bail.
        return

    for device_id in device_ids:
        logger.debug(
            "Notifying about update %r/%r, ID: %r", user_id, device_id, position
        )

    room_ids = await self.store.get_rooms_for_user(user_id)

    # specify the user ID too since the user should always get their own device list
    # updates, even if they aren't in any rooms.
    self.notifier.on_new_event(
        "device_list_key", position, users=[user_id], rooms=room_ids
    )

    if hosts:
        logger.info("Sending device list update notif for %r to: %r", user_id, hosts)
        for host in hosts:
            self.federation_sender.send_device_messages(host)
            log_kv({"message": "sent device update to host", "host": host})