pallets/flask · error · RuntimeError

Install Flask with the 'async' extra in order to use async v

Error message

Install Flask with the 'async' extra in order to use async views.

What it means

Raised in `async_to_sync()` (src/flask/app.py:1096) when importing `asgiref.sync.async_to_sync` fails. Flask supports `async def` views by wrapping the coroutine with asgiref's event-loop bridge, but `asgiref` is an optional dependency installed only via the `flask[async]` extra — without it, Flask cannot run the coroutine inside its sync WSGI worker.

Source

Thrown at src/flask/app.py:1096

    def async_to_sync(
        self, func: t.Callable[..., t.Coroutine[t.Any, t.Any, t.Any]]
    ) -> t.Callable[..., t.Any]:
        """Return a sync function that will run the coroutine function.

        .. code-block:: python

            result = app.async_to_sync(func)(*args, **kwargs)

        Override this method to change how the app converts async code
        to be synchronously callable.

        .. versionadded:: 2.0
        """
        try:
            from asgiref.sync import async_to_sync as asgiref_async_to_sync
        except ImportError:
            raise RuntimeError(
                "Install Flask with the 'async' extra in order to use async views."
            ) from None

        return asgiref_async_to_sync(func)

    def url_for(
        self,
        /,
        endpoint: str,
        *,
        _anchor: str | None = None,
        _method: str | None = None,
        _scheme: str | None = None,
        _external: bool | None = None,
        **values: t.Any,
    ) -> str:
        """Generate a URL to the given endpoint with the given values.

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Install the extra: `pip install 'flask[async]'` (or add `flask[async]` / `asgiref>=3.2` to your requirements/pyproject dependencies).
  2. Rebuild your deployment image or lock file so `asgiref` is present in production, not just locally.
  3. Alternatively, convert the view back to a regular `def` if it does no real awaiting — Flask remains a sync WSGI framework and each async view runs its own event loop per request.
  4. For heavily async workloads, consider an ASGI framework (Quart) instead of Flask's per-request bridge.

Example fix

# before (requirements.txt)
flask==3.1.0

# after
flask[async]==3.1.0  # installs asgiref, enabling `async def` views
Defensive patterns

Strategy: validation

Validate before calling

import importlib.util
if importlib.util.find_spec('asgiref') is None:
    raise RuntimeError("install flask[async] to use 'async def' views")

Try / catch

try:
    app.add_url_rule('/x', view_func=my_async_view)
except RuntimeError as e:
    if 'async' in str(e):
        # dependency missing — fail fast at startup, not per-request
        raise

Prevention

When it happens

Trigger: Defining an `async def` view function, error handler, or before/after-request callback and having a request dispatch to it (or calling `app.ensure_sync`/`app.async_to_sync` directly) in an environment where the `asgiref` package is not importable.

Common situations: Adding a first async view to an existing project whose requirements pin plain `flask`; Docker/CI images built from a requirements file lacking the extra; deploying to a fresh virtualenv where asgiref was only installed locally as a transitive dependency (e.g. previously pulled in by Django/channels) and then removed.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/50d0e766d787f89d.json. Report an issue: GitHub ↗.