{"record":{"id":"858799eda55be050","repo":"RustPython/RustPython","slug":"an-asyncio-future-a-coroutine-or-an-awaitable-is","errorCode":null,"errorMessage":"An asyncio.Future, a coroutine or an awaitable is required","messagePattern":"An asyncio\\.Future, a coroutine or an awaitable is required","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/asyncio/runners.py","lineNumber":104,"sourceCode":"        return self._loop\n\n    def run(self, coro, *, context=None):\n        \"\"\"Run code in the embedded event loop.\"\"\"\n        if events._get_running_loop() is not None:\n            # fail fast with short traceback\n            raise RuntimeError(\n                \"Runner.run() cannot be called from a running event loop\")\n\n        self._lazy_init()\n\n        if not coroutines.iscoroutine(coro):\n            if inspect.isawaitable(coro):\n                async def _wrap_awaitable(awaitable):\n                    return await awaitable\n\n                coro = _wrap_awaitable(coro)\n            else:\n                raise TypeError('An asyncio.Future, a coroutine or an '\n                                'awaitable is required')\n\n        if context is None:\n            context = self._context\n\n        task = self._loop.create_task(coro, context=context)\n\n        if (threading.current_thread() is threading.main_thread()\n            and signal.getsignal(signal.SIGINT) is signal.default_int_handler\n        ):\n            sigint_handler = functools.partial(self._on_sigint, main_task=task)\n            try:\n                signal.signal(signal.SIGINT, sigint_handler)\n            except ValueError:\n                # `signal.signal` may throw if `threading.main_thread` does\n                # not support signals (e.g. embedded interpreter with signals\n                # not registered - see gh-91880)\n                sigint_handler = None","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/RustPython/RustPython/blob/aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd/Lib/asyncio/runners.py#L86-L122","documentation":"Runner.run() accepts a coroutine, or any awaitable (futures, objects with __await__) which it wraps transparently via _wrap_awaitable. Passing anything else — an int, str, list, an already-computed result, or a coroutine function that was never called — raises TypeError('An asyncio.Future, a coroutine or an awaitable is required'). This mirrors asyncio.run()'s contract for its main argument.","triggerScenarios":"runner.run(42) or runner.run('text'); runner.run(main) (function object instead of main()); passing the return value of a synchronous client call; generic driver code receiving 'work' of unknown type.","commonSituations":"Forgetting the call parentheses on the coroutine function; passing results of sync libraries (requests, database drivers) into the Runner; wrappers that accept either a value or a coroutine without distinguishing them.","solutions":["Pass the coroutine object: runner.run(main(args)) — note the parentheses","Pre-check arbitrary work with inspect.iscoroutine(work) or inspect.isawaitable(work) before calling run()","Wrap plain values in an async function: runner.run(process(value))"],"exampleFix":"# before\nrunner.run(main)   # function object, not a coroutine -> TypeError\n\n# after\nrunner.run(main()) # coroutine object","handlingStrategy":"type-guard","validationCode":"import inspect\n\ndef as_awaitable(work):\n    if inspect.iscoroutine(work) or inspect.isawaitable(work):\n        return work\n    raise TypeError(\n        f\"Runner.run needs a coroutine or awaitable, got {type(work).__name__}\")\n\nrunner.run(as_awaitable(work))","typeGuard":"import inspect\n\ndef is_awaitable(obj) -> bool:\n    return inspect.iscoroutine(obj) or inspect.isawaitable(obj)","tryCatchPattern":null,"preventionTips":["Always call the coroutine function: run(main()), not run(main)","Type-annotate the parameter as Coroutine and enforce with mypy","Use inspect.isawaitable() as the general pre-check before passing arbitrary 'work' objects"],"tags":["asyncio","runner","type-error","awaitable","python"],"backgroundTag":"awaitable-required","analyzedSha":"aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd","analyzedAt":"2026-08-17T00:37:52.100Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}