{"record":{"id":"264157fb8b8447e5","repo":"python/cpython","slug":"future-object-is-not-initialized","errorCode":null,"errorMessage":"Future object is not initialized.","messagePattern":"Future object is not initialized\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Lib/asyncio/futures.py","lineNumber":136,"sourceCode":"        return self.__log_traceback\n\n    @_log_traceback.setter\n    def _log_traceback(self, val):\n        if val:\n            raise ValueError('_log_traceback can only be set to False')\n        self.__log_traceback = False\n\n    @property\n    def _asyncio_awaited_by(self):\n        if self.__asyncio_awaited_by is None:\n            return None\n        return frozenset(self.__asyncio_awaited_by)\n\n    def get_loop(self):\n        \"\"\"Return the event loop the Future is bound to.\"\"\"\n        loop = self._loop\n        if loop is None:\n            raise RuntimeError(\"Future object is not initialized.\")\n        return loop\n\n    def _make_cancelled_error(self):\n        \"\"\"Create the CancelledError to raise if the Future is cancelled.\n\n        This should only be called once when handling a cancellation since\n        it erases the saved context exception value.\n        \"\"\"\n        if self._cancelled_exc is not None:\n            exc = self._cancelled_exc\n            self._cancelled_exc = None\n            return exc\n\n        if self._cancel_message is None:\n            exc = exceptions.CancelledError()\n        else:\n            exc = exceptions.CancelledError(self._cancel_message)\n        return exc","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/asyncio/futures.py#L118-L154","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Call super().__init__() before any use of self.get_loop() in subclasses","Discard futures whose construction failed; do not retry operations on them","Use asyncio.get_running_loop() at creation time and pass the loop explicitly"],"exampleFix":"# before\nclass MyFuture(asyncio.Future):\n    def __init__(self, cb):\n        self.get_loop().call_soon(cb)  # _loop still None\n        super().__init__()\n\n# after\nclass MyFuture(asyncio.Future):\n    def __init__(self, cb):\n        super().__init__()\n        self.get_loop().call_soon(cb)","handlingStrategy":"validation","validationCode":"loop = getattr(fut, '_loop', None)\nif loop is None:\n    # future not initialized; discard it","typeGuard":"def future_is_ready(fut) -> bool:\n    return getattr(fut, '_loop', None) is not None","tryCatchPattern":null,"preventionTips":["Finish super().__init__() before touching self in subclasses","Drop half-constructed objects on exception; never retry operations on them","Pass the loop explicitly at creation: Future(loop=loop)"],"tags":["asyncio","future","initialization"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}