aio-libs/aiohttp · error · RuntimeError

Failed to get module name.

Error message

Failed to get module name.

What it means

Raised by BaseKey.__init__ when the frame-walk to find an enclosing '<module>' frame fails, i.e. no module-level frame exists on the call stack when an AppKey/RequestKey/ResponseKey is instantiated. The prefix requires a module name to deduplicate keys; without it, construction is refused (RuntimeError).

Source

Thrown at aiohttp/helpers.py:917

    __slots__ = ("_name", "_t", "__orig_class__")

    # This may be set by Python when instantiating with a generic type. We need to
    # support this, in order to support types that are not concrete classes,
    # like Iterable, which can't be passed as the second parameter to __init__.
    __orig_class__: type[object]

    # TODO(PY314): Change Type to TypeForm (this should resolve unreachable below).
    def __init__(self, name: str, t: type[_T] | None = None):
        # Prefix with module name to help deduplicate key names.
        frame = inspect.currentframe()
        while frame:
            if frame.f_code.co_name == "<module>":
                module: str = frame.f_globals["__name__"]
                break
            frame = frame.f_back
        else:
            raise RuntimeError("Failed to get module name.")

        # https://github.com/python/mypy/issues/14209
        self._name = module + "." + name  # type: ignore[possibly-undefined]
        self._t = t

    def __lt__(self, other: object) -> bool:
        if isinstance(other, BaseKey):
            return self._name < other._name
        return True  # Order BaseKey above other types.

    def __repr__(self) -> str:
        t = self._t
        if t is None:
            with suppress(AttributeError):
                # Set to type arg.
                t = get_args(self.__orig_class__)[0]

        if t is None:

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Define keys at module top level so a '<module>' frame is reachable.
  2. Avoid constructing keys inside exec/eval; import a module that declares them.
  3. If unavoidable, factor key creation into a normal imported function.

Example fix

// before
exec("key = AppKey('x')")
// after
# in myapp/keys.py
from aiohttp import AppKey
key = AppKey('x')
Defensive patterns

Strategy: validation

Validate before calling

import inspect
def can_resolve_module():
    frame = inspect.currentframe()
    while frame:
        if frame.f_code.co_name == '<module>' and '__name__' in frame.f_globals:
            return True
        frame = frame.f_back
    return False

Prevention

When it happens

Trigger: Instantiating AppKey() from within a C extension frame, an exec/eval with no globals['__name__'], or in an environment where inspect.currentframe()/f_back is None (restricted or patched interpreters). In normal module-level or function-level code this never fires.

Common situations: Building keys dynamically via exec(); sandboxed environments stripping frames; unusual interpreters (PyPy edge cases) where f_back chains differ.

Related errors


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/d2ab7dbde436ea50.json. Report an issue: GitHub.