pytest "async def functions are not natively supported" after upgrading pytest-asyncio: how to fix
Fixes the pytest "async def functions are not natively supported" error that appears after upgrading pytest-asyncio. It explains the strict-vs-auto mode change, shows how to opt into auto mode or add the marker, and how to verify the plugin version you actually have. Use when async tests that used to run now error at collection after a pytest-asyncio upgrade. Not for async tests that run but fail, and not for choosing an async framework - this is the collection error only.
Tell pytest-asyncio to run your async tests automatically. Newer pytest-asyncio versions default to strict mode, which skips (or errors on) async test functions unless each one carries the asyncio marker. The one-line fix is setting asyncio_mode to auto in your pytest config, which restores the old behavior of running every async test. If you would rather be explicit, add the marker to each async test instead. The error is a config problem, not a code problem - your tests are fine.
pytest "async def functions are not natively supported" after upgrading pytest-asyncio: how to fixSteps
Confirm the installed version: run pip show pytest-asyncio (or your lockfile) and check the version. The strict-by-default behavior arrived in the 0.21 line and stayed in later releases. Expected: you know the exact installed version, so you can read the right changelog section.
Open your pytest config (pyproject.toml under tool.pytest.inioptions, or pytest.ini / setup.cfg) and add asynciomode = auto. Re-run the suite. Expected: the collection error is gone and async tests run again.
If you prefer explicit markers, skip the config change and decorate each async test with the pytest asyncio marker instead. This is the strict-mode way and it also fixes the error. Expected: every async def test carries the marker and collection succeeds.
Run the full suite and check the test count matches what you had before the upgrade. Strict mode can silently skip unmarked async tests instead of erroring, so a green run with fewer tests is a trap. Expected: the collected test count matches the pre-upgrade count - nothing is silently skipped.
Pin pytest-asyncio in your lockfile so the next upgrade is deliberate, not a surprise in CI. Expected: the version is pinned and future upgrades go through a conscious review.
Use this when
- the exact error "async def functions are not natively supported" appears at collection after a pytest-asyncio upgrade
- async tests used to run and now error or silently skip
- you are on pytest-asyncio 0.21 or newer
Not for this skill when
- async tests that run but fail inside the coroutine (that is a test bug, not a collection config problem)
- deciding between asyncio, trio, or anyio as your async framework - this skill only fixes the collection error
Variant phrasings
pytest-asyncio strict mode vs auto mode
Strict mode requires the marker on every async test; auto mode runs all async tests without markers. The upgrade flipped the default to strict, which is why previously working suites broke.
async def test skipped instead of erroring
Same root cause, quieter symptom. Count your collected tests - a drop after the upgrade means strict mode is skipping unmarked async tests.
Why it happens
pytest-asyncio changed its default asyncio_mode from auto to strict. In auto mode the plugin runs every async def test function; in strict mode it only runs tests explicitly marked, and unmarked ones error (or skip) at collection with this message. Upgrading the plugin flips the default under a suite that was written for auto mode, so every async test breaks at once even though none of the test code changed.
Edge cases
- some async tests use a different event loop scope (module or session fixtures): auto mode handles the common case, but custom loop scopes still need explicit config
- you use anyio or trio: pytest-asyncio only drives asyncio; mixed async backends need their own plugins
- the marker approach with hundreds of async tests: use auto mode instead of editing every test, then migrate to markers gradually if you want strictness
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_Rv3l7uhbSjIiI9WcTSZoUQ