aio-libs/aiohttp · error · TypeError
Prefix must be str
Error message
Prefix must be str
What it means
Raised by Application.add_subapp when prefix is not a str instance. Subapps are mounted under a URL path prefix, and aiohttp both string-slices (rstrip('/')) and uses the prefix in URL matching, so a non-str type (Path, bytes, None) is rejected up front. Use add_subapp(str(prefix), subapp) if you have a pathlib.Path.
Source
Thrown at aiohttp/web_app.py:277
return asyncio.get_running_loop().get_debug()
def _reg_subapp_signals(self, subapp: "Application") -> None:
def reg_handler(signame: str) -> None:
subsig = getattr(subapp, signame)
async def handler(app: "Application") -> None:
await subsig.send(subapp)
appsig = getattr(self, signame)
appsig.append(handler)
reg_handler("on_startup")
reg_handler("on_shutdown")
reg_handler("on_cleanup")
def add_subapp(self, prefix: str, subapp: "Application") -> PrefixedSubAppResource:
if not isinstance(prefix, str):
raise TypeError("Prefix must be str")
prefix = prefix.rstrip("/")
if not prefix:
raise ValueError("Prefix cannot be empty")
factory = partial(PrefixedSubAppResource, prefix, subapp)
return self._add_subapp(factory, subapp)
def _add_subapp(
self, resource_factory: Callable[[], _Resource], subapp: "Application"
) -> _Resource:
if self.frozen:
raise RuntimeError("Cannot add sub application to frozen application")
if subapp.frozen:
raise RuntimeError("Cannot add frozen application")
resource = resource_factory()
self.router.register_resource(resource)
self._reg_subapp_signals(subapp)
self._subapps.append(subapp)
subapp.pre_freeze()View on GitHub (pinned to c0ef574e29)
Solutions
- Convert to str: `app.add_subapp(str(prefix), subapp)`.
- Keep prefixes as plain strings in config rather than Path objects.
- Validate the type at config load time.
Example fix
// before
app.add_subapp(pathlib.Path('/admin'), admin_app) # Path, not str
// after
app.add_subapp('/admin', admin_app)
# or
app.add_subapp(str(pathlib.Path('/admin')), admin_app) Defensive patterns
Strategy: type-guard
Validate before calling
def safe_add_subapp(app, prefix, subapp):
if not isinstance(prefix, str):
raise TypeError(f'prefix must be str, got {type(prefix).__name__}')
return app.add_subapp(prefix, subapp) Type guard
from typing import Any, TypeGuard
def is_str_prefix(p: Any) -> TypeGuard[str]:
return isinstance(p, str) Prevention
- Keep prefixes as plain str in config.
- Coerce pathlib.Path via str() at the boundary.
- Validate prefix type at config load.
When it happens
Trigger: Calling app.add_subapp(pathlib.Path('/admin'), subapp); passing bytes prefix b'/admin'; passing None or a custom path object.
Common situations: Building prefixes from pathlib.Path; reading prefix from config that yields a non-str type; refactoring that drops a str() conversion; templating that emits None on missing key.
Related errors
- Domain must be str
- Prefix cannot be empty
- Cannot add sub application to frozen application
- Cannot add frozen application
- 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/e48e64d33a003ae4.json.
Report an issue: GitHub.