aio-libs/aiohttp · error · RuntimeError
Call runner.setup() before making a site
Error message
Call runner.setup() before making a site
What it means
BaseSite.__init__ requires runner.server to be non-None (line 102-103). runner.server is only set after await runner.setup() runs _make_server (line 345). Constructing a TCPSite/UnixSite/SockSite/NamedPipeSite before setup() raises RuntimeError.
Source
Thrown at aiohttp/web_runner.py:103
code = 1
def _raise_graceful_exit() -> None:
raise GracefulExit()
class BaseSite(ABC):
__slots__ = ("_runner", "_ssl_context", "_backlog", "_server")
def __init__(
self,
runner: "BaseRunner[Any]",
*,
ssl_context: SSLContext | None = None,
backlog: int = 128,
) -> None:
if runner.server is None:
raise RuntimeError("Call runner.setup() before making a site")
self._runner = runner
self._ssl_context = ssl_context
self._backlog = backlog
self._server: asyncio.Server | None = None
@property
@abstractmethod
def name(self) -> str:
"""Return the name of the site (e.g. a URL)."""
@abstractmethod
async def start(self) -> None:
self._runner._reg_site(self)
async def stop(self) -> None:
self._runner._check_site(self)
if self._server is not None: # Maybe not started yet
self._server.close()View on GitHub (pinned to c0ef574e29)
Solutions
- Always call `await runner.setup()` before constructing any site.
- Order your startup: runner = AppRunner(app); await runner.setup(); site = TCPSite(runner, ...); await site.start().
- Use web.AppRunner together with aiohttp.web.run_app to avoid manual ordering.
Example fix
# before runner = AppRunner(app) site = TCPSite(runner, '0.0.0.0', 8080) # raises RuntimeError await runner.setup() # after runner = AppRunner(app) await runner.setup() site = TCPSite(runner, '0.0.0.0', 8080) await site.start()
Defensive patterns
Strategy: validation
Validate before calling
async def make_site(runner, *site_args, **site_kw):
if runner.server is None:
await runner.setup()
from aiohttp.web import TCPSite # or chosen site type
return TCPSite(runner, *site_args, **site_kw) Prevention
- Always `await runner.setup()` before constructing any site.
- Write a startup helper that enforces the runner->setup->site->start order.
- Use aiohttp.web.run_app for simple cases to avoid manual ordering.
When it happens
Trigger: Creating `site = TCPSite(runner, ...)` before calling `await runner.setup()`, or forgetting the setup() call entirely in the startup sequence.
Common situations: Bootstrapping an aiohttp app with AppRunner/ServerRunner; reordering startup code; copy-paste that dropped the setup() line.
Related errors
- Site {site} is already registered in runner {self}
- Site {site} is not registered in runner {self}
- Response has not been started
- WebSocket connection is closed.
- Compress wbits must between 9 and 15, zlib does not support
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/aac0922c4ae7ebc4.json.
Report an issue: GitHub.