python/cpython · error · RuntimeError

Future object is not initialized.

Error message

Future object is not initialized.

What it means

Future.get_loop() raises RuntimeError when self._loop is None, i.e. the future exists but __init__ never completed (or the state was cleared). It is the read-side counterpart of the 'already initialized' guard: the object is unusable because it has no loop binding.

Source

Thrown at Lib/asyncio/futures.py:136

        return self.__log_traceback

    @_log_traceback.setter
    def _log_traceback(self, val):
        if val:
            raise ValueError('_log_traceback can only be set to False')
        self.__log_traceback = False

    @property
    def _asyncio_awaited_by(self):
        if self.__asyncio_awaited_by is None:
            return None
        return frozenset(self.__asyncio_awaited_by)

    def get_loop(self):
        """Return the event loop the Future is bound to."""
        loop = self._loop
        if loop is None:
            raise RuntimeError("Future object is not initialized.")
        return loop

    def _make_cancelled_error(self):
        """Create the CancelledError to raise if the Future is cancelled.

        This should only be called once when handling a cancellation since
        it erases the saved context exception value.
        """
        if self._cancelled_exc is not None:
            exc = self._cancelled_exc
            self._cancelled_exc = None
            return exc

        if self._cancel_message is None:
            exc = exceptions.CancelledError()
        else:
            exc = exceptions.CancelledError(self._cancel_message)
        return exc

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Call super().__init__() before any use of self.get_loop() in subclasses
  2. Discard futures whose construction failed; do not retry operations on them
  3. Use asyncio.get_running_loop() at creation time and pass the loop explicitly

Example fix

# before
class MyFuture(asyncio.Future):
    def __init__(self, cb):
        self.get_loop().call_soon(cb)  # _loop still None
        super().__init__()

# after
class MyFuture(asyncio.Future):
    def __init__(self, cb):
        super().__init__()
        self.get_loop().call_soon(cb)
Defensive patterns

Strategy: validation

Validate before calling

loop = getattr(fut, '_loop', None)
if loop is None:
    # future not initialized; discard it

Type guard

def future_is_ready(fut) -> bool:
    return getattr(fut, '_loop', None) is not None

Prevention

When it happens

Trigger: Calling get_loop() on a Future whose __init__ raised before loop assignment; instances created via __new__ without initialization; accessing get_loop() inside a subclass __init__ before super().__init__() ran.

Common situations: Subclass constructors that use self.get_loop() before super().__init__(); exception paths that leave a half-built future referenced; serialization frameworks instantiating objects with __new__ only.

Related errors


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