RuntimeWarning: coroutine was never awaited
This warning occurs when an asynchronous function (coroutine) is called like a regular function without the 'await' keyword.
Usually happens because:
- ☑ Missing 'await' keyword prefix when calling an async def function
- ☑ Calling asynchronous functions inside synchronous contexts
- ☑ Orphaned coroutine generator objects falling out of scope
🔍 Quick Checklist:
What is RuntimeWarning: coroutine was never awaited?
The 'RuntimeWarning: coroutine was never awaited' is raised by the Python garbage collector when a coroutine object is garbage collected without ever being executed. In Python's asyncio subsystem, calling an 'async def' function does not run its body immediately; instead, it returns a lazy coroutine generator object. To actually execute the code inside the coroutine, you must explicitly use the 'await' keyword inside another async function, or run it through 'asyncio.run()'.
Common Causes
- Forgetting the await keyword: Invoking 'my_async_func()' like a standard synchronous function without prepending 'await'.
- Misconfigured call chains: Running async methods from synchronous code blocks without binding them to an active event loop.
- Creating tasks without executing them: Storing coroutine objects inside variables or lists and letting them fall out of scope without awaiting them.
| Cause | Frequency |
|---|---|
| Forgetting the await keyword on async function calls | ⭐⭐⭐⭐⭐ |
| Running async code from synchronous contexts | ⭐⭐⭐⭐ |
| Orphaning coroutine objects inside variables | ⭐⭐⭐ |
Common Mistakes
- Calling an async function inside a standard synchronous function without registering it to an event loop, leaving the coroutine unexecuted.
- Assuming list comprehensions of async calls (e.g. `[fetch() for _ in range(5)]`) executes them (this only creates a list of lazy unawaited coroutine objects).
How to Fix
Python Operations & Verification
Prepend async calls with the await keyword inside async block environments to ensure execution.
import asyncio
async def fetch_data():
await asyncio.sleep(0.1)
return "data"
async def main():
# Correct: awaits execution of the coroutine
result = await fetch_data()
print(result)
asyncio.run(main())Platform Specific Fixes
Enable asyncio debug variables in bash to print allocation tracebacks when warnings trigger.
export PYTHONASYNCIODEBUG=1
python3 script.pyBest Practices
- Enable async linting checks inside editor profiles to automatically highlight unawaited coroutine calls.
- Utilize Python's debug parameters in testing pipelines to fail builds when unawaited warnings trigger.
Frequently Asked Questions (FAQ)
Q: What does 'coroutine was never awaited' mean?
It means you called an asynchronous function ('async def') but did not await it. Calling an async function only creates a coroutine object; it does not execute the code inside unless it is awaited.
Q: How do I execute a coroutine?
Prepend it with the 'await' keyword inside an async function: 'await my_function()'. If you are in the top-level script scope, start the event loop using 'asyncio.run(my_function())'.
Q: Can I use await inside a synchronous function?
No, the 'await' keyword can only be used inside functions declared with 'async def'. To run async code from a synchronous function, use 'asyncio.run()' or interact with an active event loop.
Q: How do I debug unawaited coroutines?
Enable asyncio debug mode by setting the environment variable 'PYTHONASYNCIODEBUG=1' before running your script. This will print a traceback showing exactly where the unawaited coroutine was originally created.