python/cpython · error · RuntimeError
await wasn't used with future
Error message
await wasn't used with future
What it means
Future.__await__ yields the future once so the event loop can resume the waiter when it completes; after resuming, done() must be True. If the coro was driven by something that did not actually await (bare next() on __iter__, custom drivers that ignore the yielded future), the future is still pending and this RuntimeError fires. It means 'you iterated a future without a real awaiter'.
Source
Thrown at Lib/asyncio/futures.py:301
if isinstance(exception, StopIteration):
new_exc = RuntimeError("StopIteration interacts badly with "
"generators and cannot be raised into a "
"Future")
new_exc.__cause__ = exception
new_exc.__context__ = exception
exception = new_exc
self._exception = exception
self._exception_tb = exception.__traceback__
self._state = _FINISHED
self.__schedule_callbacks()
self.__log_traceback = True
def __await__(self):
if not self.done():
self._asyncio_future_blocking = True
yield self # This tells Task to wait for completion.
if not self.done():
raise RuntimeError("await wasn't used with future")
return self.result() # May raise too.
__iter__ = __await__ # make compatible with 'yield from'.
# Needed for testing purposes.
_PyFuture = Future
def _get_loop(fut):
# Tries to call Future.get_loop() if it's available.
# Otherwise fallbacks to using the old '_loop' property.
try:
get_loop = fut.get_loop
except AttributeError:
pass
else:
return get_loop()View on GitHub (pinned to bc6749cc3b)
Solutions
- Always consume futures with await inside a real asyncio Task (asyncio.run, loop.create_task)
- In custom drivers, after the future completes, resume the coroutine with send/close properly
- Replace manual iteration with await asyncio.wait([fut])
Example fix
# before coro = future.__await__() next(coro) # manual drive -> RuntimeError on next iteration # after result = await future # inside a coroutine run by asyncio
Defensive patterns
Strategy: validation
Validate before calling
# ensure the awaiter runs inside a real task assert asyncio.current_task() is not None
Prevention
- Never drive coroutines with raw next()/send() outside asyncio
- Use await exclusively inside tasks created by the loop
- Test custom drivers against both pending and completed futures
When it happens
Trigger: Manually driving a coroutine that awaits a future with next(coro.__await__()) outside a loop; using 'yield from future' inside a generator consumed by non-asyncio machinery; a Task implementation that resumes the coroutine without completing the future.
Common situations: Custom task/trampoline implementations; calling coro.send(None) once in tests; mixing curio/trio-style drivers with asyncio futures; debugging tools stepping through coroutines manually.
Related errors
- Unknown thread safety level {level!r} for {name!r}. Valid le
- coroutine ignored GeneratorExit
- {self.__class__.__name__} object is already initialized
- Future object is not initialized.
- A future is required for source argument
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/6bfe916326503203.
Report an issue: GitHub.