aio-libs/aiohttp · error · RuntimeError
Failed to get module name.
Error message
Failed to get module name.
What it means
BaseKey.__init__ raises RuntimeError when it cannot find a '<module>' frame in the call stack by walking frame.f_back. BaseKey (and its subclass AppKey) prefixes its internal name with the calling module's __name__ for deduplication. If instantiated from a context with no module-level frame (e.g. a deeply nested call where the module frame has been optimized away), the loop exits without breaking and the else clause fires.
Solutions
- Define AppKey instances at module level in a .py file (the normal use case)
- If using exec/eval, ensure the code object has a '<module>' frame by providing a proper __name__ in globals
- Avoid creating AppKey dynamically in nested function calls — define them at module scope
Example fix
# before (dynamic creation may fail)
key = eval('AppKey("my_key")')
# after (module-level definition)
# myapp/keys.py
from aiohttp.web import AppKey
my_key = AppKey('my_key', str) Defensive patterns
Strategy: validation
Validate before calling
import inspect
def can_resolve_module_name() -> bool:
frame = inspect.currentframe()
while frame:
if frame.f_code.co_name == '<module>':
return True
frame = frame.f_back
return False
if not can_resolve_module_name():
raise RuntimeError('Cannot create AppKey: no module frame in call stack') Try / catch
try:
my_key = AppKey('my_key', str)
except RuntimeError as e:
if 'Failed to get module name' in str(e):
# Define at module level instead of dynamically
raise RuntimeError('AppKey must be defined at module level')
raise Prevention
- Always define AppKey instances at module scope in a .py file
- Avoid creating keys in eval/exec/REPL contexts
- Use a dedicated keys.py module for all AppKey definitions
When it happens
Trigger: Creating an AppKey or BaseKey from a context where inspect.currentframe() and walking f_back cannot reach a frame with co_name == '<module>'. This can happen in certain REPL environments, eval/exec contexts, or when frame introspection is limited by the Python implementation (e.g. some JIT or restricted environments).
Common situations: Defining AppKey instances in interactive REPL sessions where the module frame structure differs; using exec() to dynamically define keys; running under Python implementations with limited frame support; deeply nested class bodies where frame walking misses the module frame.
Related errors
- Changing state of started or joined application is forbidden
- Concurrent call to receive() is not allowed
- Inheritance class from ChainMapProxy is forbidden
- Inheritance class from web.Application is forbidden
- KeyError
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/d2ab7dbde436ea50.
Report an issue: GitHub.
Appendix: 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 d041d4d0fd)