aio-libs/aiohttp · error · RuntimeError
Site {site} is already registered in runner {self}
Error message
Site {site} is already registered in runner {self} What it means
BaseRunner._reg_site (line 386-388) rejects registering the same site object twice. Each site's start() calls self._runner._reg_site(self), so starting the same site instance twice (or registering it twice) is a logic error.
Source
Thrown at aiohttp/web_runner.py:388
loop = asyncio.get_running_loop()
try:
loop.remove_signal_handler(signal.SIGINT)
loop.remove_signal_handler(signal.SIGTERM)
except NotImplementedError:
# remove_signal_handler is not implemented on Windows
pass
@abstractmethod
async def _make_server(self) -> Server[_Request]:
"""Return a new server for the runner to serve requests."""
@abstractmethod
async def _cleanup_server(self) -> None:
"""Run any cleanup steps after the server is shutdown."""
def _reg_site(self, site: BaseSite) -> None:
if site in self._sites:
raise RuntimeError(f"Site {site} is already registered in runner {self}")
self._sites.append(site)
def _check_site(self, site: BaseSite) -> None:
if site not in self._sites:
raise RuntimeError(f"Site {site} is not registered in runner {self}")
def _unreg_site(self, site: BaseSite) -> None:
if site not in self._sites:
raise RuntimeError(f"Site {site} is not registered in runner {self}")
self._sites.remove(site)
class ServerRunner(BaseRunner[BaseRequest]):
"""Low-level web server runner"""
__slots__ = ("_web_server",)
def __init__(View on GitHub (pinned to c0ef574e29)
Solutions
- Call site.start() exactly once per site instance.
- Create a fresh site object for each (re)start cycle.
- Track started state yourself and skip if already started.
Example fix
# before site = TCPSite(runner, '0.0.0.0', 8080) await site.start() await site.start() # second start re-registers -> RuntimeError # after site = TCPSite(runner, '0.0.0.0', 8080) await site.start() # only once
Defensive patterns
Strategy: validation
Validate before calling
started = set()
async def start_once(site, runner, started):
if site in runner.sites or id(site) in started:
return
await site.start()
started.add(id(site)) Prevention
- Call site.start() exactly once per site instance.
- Create a new site object for each restart cycle.
- Track started state to make start idempotent.
When it happens
Trigger: Calling `await site.start()` twice on the same TCPSite/UnixSite/SockSite/NamedPipeSite instance; reusing a site object after stop() without re-creating it.
Common situations: Restart logic that reuses site objects; calling start() in a retry loop; double-await from concurrent tasks.
Related errors
- Call runner.setup() before making a site
- 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/0393d3a420d38be5.json.
Report an issue: GitHub.