# Buggy code
def observe(self) -> defer.Deferred:
    """Observe the underlying deferred.

    This returns a brand new deferred that is resolved when the underlying
    deferred is resolved. Interacting with the returned deferred does not
    effect the underdlying deferred.
    """
    if not self._result:
        d = defer.Deferred()

        def remove(r):
            self._observers.discard(d)
            return r

        d.addBoth(remove)

        self._observers.add(d)
        return d
    else:
        success, res = self._result
        return defer.succeed(res) if success else defer.fail(res)


# Traceback (TypeError)
homeserver - 2018-05-18 00:40:04,123 - synapse.federation.federation_server - 643 - ERROR - Failed to handle edu 'm.receipt'
Traceback (most recent call last):
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/federation/federation_server.py", line 639, in on_edu
yield handler(origin, content)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
result = result.throwExceptionIntoGenerator(g)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/python/failure.py", line 422, in throwExceptionIntoGenerator
return g.throw(self.type, self.value, self.tb)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/receipts.py", line 84, in _received_remote_receipt
yield self._handle_new_receipts(receipts)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
result = result.throwExceptionIntoGenerator(g)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/python/failure.py", line 422, in throwExceptionIntoGenerator
return g.throw(self.type, self.value, self.tb)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/handlers/receipts.py", line 101, in _handle_new_receipts
room_id, receipt_type, user_id, event_ids, data
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
result = result.throwExceptionIntoGenerator(g)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/python/failure.py", line 422, in throwExceptionIntoGenerator
return g.throw(self.type, self.value, self.tb)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/receipts.py", line 456, in insert_receipt
stream_id=stream_id,
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
result = g.send(result)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/_base.py", line 323, in runInteraction
after_callback(*after_args, **after_kwargs)
File "/home/matrix/.synapse/local/lib/python2.7/site-packages/synapse/storage/receipts.py", line 308, in _invalidate_get_users_with_receipts_in_room
if user_id in res:
TypeError: argument of type 'ObservableDeferred' is not iterable

# Fixed code
def observe(self) -> defer.Deferred:
    """Observe the underlying deferred.

    This returns a brand new deferred that is resolved when the underlying
    deferred is resolved. Interacting with the returned deferred does not
    effect the underlying deferred.
    """
    if not self._result:
        d = defer.Deferred()

        def remove(r):
            self._observers.discard(d)
            return r

        d.addBoth(remove)

        self._observers.add(d)
        return d
    else:
        success, res = self._result
        return defer.succeed(res) if success else defer.fail(res)