aio-libs/aiohttp · error · TypeError

Inheritance class from web.Application is forbidden

Error message

Inheritance class {cls.__name__} from web.Application is forbidden

What it means

Raised by Application.__init_subclass__ when a user class subclasses web.Application. aiohttp's Application is designed to be configured via composition (routers, middlewares, signals, cleanup contexts) rather than inheritance, and subclassing can break freezing, signal wiring, and internal invariants. The metaclass-level hook makes subclassing impossible at class-creation time.

Solutions

  1. Use composition: instantiate app = web.Application(...) and attach helpers as attributes or in the application mapping via app['key'].
  2. Put shared logic in middleware or a cleanup context registered on a normal Application instance.
  3. For grouping, use add_subapp / sub-applications rather than inheritance.

Example fix

# before
class MyApp(web.Application):
    def helper(self): ...

# after
app = web.Application()
def helper(app):
    ...
app['helper'] = helper
Defensive patterns

Strategy: type-guard

Validate before calling

app = web.Application(middlewares=[...])
# never: class MyApp(web.Application)
# attach helpers instead:
app['helpers'] = MyHelpers()

Type guard

def is_application(obj) -> bool:
    return type(obj) is web.Application or (isinstance(obj, web.Application) and type(obj).__mro__[1] is web.Application)

Prevention

When it happens

Trigger: Writing class MyApp(web.Application): ...; trying to add methods or attributes by inheriting from Application; framework wrappers that attempt to subclass instead of compose.

Common situations: Migrating from other frameworks (Flask/Django) where subclassing an app class is idiomatic; attempting to bundle helper methods onto the app object.

Understand the failure class

Related errors


AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11). Data as JSON: /api/errors/5ef21e76c60966af. Report an issue: GitHub.

Appendix: source

Thrown at aiohttp/web_app.py:135

        # initialized on freezing
        self._run_middlewares: bool | None = None

        self._state: dict[AppKey[Any] | str, object] = {}
        self._frozen = False
        self._pre_frozen = False
        self._subapps: _Subapps = []

        self._on_response_prepare: _RespPrepareSignal = Signal(self)
        self._on_startup: _AppSignal = Signal(self)
        self._on_shutdown: _AppSignal = Signal(self)
        self._on_cleanup: _AppSignal = Signal(self)
        self._cleanup_ctx = CleanupContext()
        self._on_startup.append(self._cleanup_ctx._on_startup)
        self._on_cleanup.append(self._cleanup_ctx._on_cleanup)
        self._client_max_size = client_max_size

    def __init_subclass__(cls: type["Application"]) -> None:
        raise TypeError(
            f"Inheritance class {cls.__name__} from web.Application is forbidden"
        )

    # MutableMapping API

    def __eq__(self, other: object) -> bool:
        return self is other

    @overload  # type: ignore[override]
    def __getitem__(self, key: AppKey[_T]) -> _T: ...

    @overload
    def __getitem__(self, key: str) -> Any: ...

    def __getitem__(self, key: str | AppKey[_T]) -> Any:
        return self._state[key]

    def _check_frozen(self) -> None:

View on GitHub (pinned to d041d4d0fd)