python/cpython · error · RuntimeError

{self.__class__.__name__} object is already initialized

Error message

{self.__class__.__name__} object is already initialized

What it means

asyncio.Future.__init__ raises RuntimeError if the future already has a bound loop, i.e. __init__ is being run twice on the same instance. This happens when a subclass forgets to call super().__init__() correctly or when __init__ is re-invoked on a reused/pooled object.

Source

Thrown at Lib/asyncio/futures.py:83

    #   the difference between
    #   `await Future()` or `yield from Future()` (correct) vs.
    #   `yield Future()` (incorrect).
    _asyncio_future_blocking = False

    # Used by the capture_call_stack() API.
    __asyncio_awaited_by = None

    __log_traceback = False

    def __init__(self, *, loop=None):
        """Initialize the future.

        The optional event_loop argument allows explicitly setting the event
        loop object used by the future. If it's not provided, the future uses
        the default event loop.
        """
        if self._loop is not None:
            raise RuntimeError(f"{self.__class__.__name__} object is already "
                                "initialized")

        if loop is None:
            self._loop = events.get_event_loop()
        else:
            self._loop = loop
        self._callbacks = []
        if self._loop.get_debug():
            self._source_traceback = format_helpers.extract_stack(
                sys._getframe(1))

    def __repr__(self):
        return base_futures._future_repr(self)

    def __del__(self):
        if not self.__log_traceback:
            # set_exception() was not called, or result() or exception()
            # has consumed the exception

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Ensure super().__init__() is called exactly once in the subclass constructor
  2. Do not reuse or manually re-initialize Future instances; create a new one
  3. Avoid deepcopy of futures; recreate them instead

Example fix

# before
class MyFuture(asyncio.Future):
    def __init__(self, *, loop=None):
        super().__init__(loop=loop)
        if loop is not None:
            super().__init__(loop=loop)  # second call -> RuntimeError

# after
class MyFuture(asyncio.Future):
    def __init__(self, *, loop=None):
        super().__init__(loop=loop)  # exactly once
Defensive patterns

Strategy: validation

Validate before calling

class MyFuture(asyncio.Future):
    def __init__(self, **kw):
        assert getattr(self, '_loop', None) is None  # not yet initialized
        super().__init__(**kw)

Prevention

When it happens

Trigger: A Future subclass whose __init__ calls super().__init__() twice; calling Future.__init__(fut) manually on an existing instance; subclass __new__ returning a cached object that was already initialized.

Common situations: Custom Future subclasses (e.g. for tracing or instrumentation); code that pools/recycles future objects; copy/deepcopy of a Future partially re-running init; refactors that moved super().__init__() into a conditional branch executed twice.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/702858c1a258ce62. Report an issue: GitHub.