langflow-ai/langflow · error · AttributeError
module {__name__!r} has no attribute {attr_name!r}
Error message
module {__name__!r} has no attribute {attr_name!r} What it means
This message lives inside a Python module template that port_bundle.py writes into the generated bundle's lazy __init__.py (PEP 562 module-level __getattr__). The generated package maps each public attribute name to a submodule via a _dynamic_imports dict; accessing any attribute NOT in that dict raises the standard AttributeError 'module <name> has no attribute <attr>' with this exact f-string. It is ordinary Python lazy-import behavior, not a migration-script failure — you hit it at runtime when using the generated lfx_<bundle> package.
Source
Thrown at scripts/migrate/port_bundle.py:286
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from lfx.components._importing import import_mod
if TYPE_CHECKING:
{type_checking_imports}
_dynamic_imports = {dynamic_imports_dict}
__all__ = {all_list}
def __getattr__(attr_name: str) -> Any:
if attr_name not in _dynamic_imports:
msg = f"module {{__name__!r}} has no attribute {{attr_name!r}}"
raise AttributeError(msg)
try:
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
except (ModuleNotFoundError, ImportError, AttributeError) as e:
msg = f"Could not import {{attr_name!r}} from {{__name__!r}}: {{e}}"
raise AttributeError(msg) from e
globals()[attr_name] = result
return result
def __dir__() -> list[str]:
return list(__all__)
'''
BASE_INIT_TEMPLATE = '''\
"""Shared base infrastructure for the {bundle} bundle.
Houses the mixin(s) every component in this bundle inherits from --View on GitHub (pinned to 976ec789d2)
Solutions
- Check the generated __init__.py's __all__ / _dynamic_imports (or call dir() on the module) to see the names the bundle actually exports.
- Import from the concrete submodule instead: `from lfx_helpers.<module> import Something`.
- If a public class is genuinely missing from _dynamic_imports, that is a port bug — re-run/patch the generated __init__ so the class is listed.
Example fix
# before import lfx_helpers lfx_helpers.ChatImput # AttributeError: module 'lfx_helpers' has no attribute 'ChatImput' # after from lfx_helpers.chat_input import ChatInput
Defensive patterns
Strategy: type-guard
Validate before calling
import lfx_helpers
name = "ChatInput"
if name not in getattr(lfx_helpers, "__all__", ()):
raise AttributeError(f"{name!r} is not exported by lfx_helpers; available: {lfx_helpers.__all__}")
obj = getattr(lfx_helpers, name) Type guard
def exports(module: object, attr: str) -> bool:
"""True if a lazy PEP 562 module advertises attr in __all__ / _dynamic_imports."""
dyn = getattr(module, "_dynamic_imports", None)
if isinstance(dyn, dict):
return attr in dyn
return attr in getattr(module, "__all__", ()) Try / catch
try:
ChatInput = lfx_helpers.ChatInput
except AttributeError as exc:
# misspelled or unregistered name — fall back to the concrete submodule
from lfx_helpers.chat_input import ChatInput Prevention
- Programmatic access should go through __all__/dir() rather than blind attribute access on lazy packages.
- After a port, grep consumers for the old attribute names to catch renames early.
- If a genuinely public class is missing from _dynamic_imports, treat it as a port bug and fix the generated __init__.
When it happens
Trigger: After a bundle is ported, calling e.g. `from lfx_helpers import Something` or `lfx_helpers.Something` where 'Something' was not registered in the generated _dynamic_imports (misspelled class, private helper, or a name that never existed in the provider).
Common situations: Consumers guessing attribute names instead of importing from submodules; a class renamed during the port; IDE autocomplete suggesting stale names from before the split.
Related errors
- git is not available; cannot check append-only invariant.
- error: invalid JSON in {source}: {exc}
- error: {source} top-level value must be an object
- error: {source} entries field must be a list
- error: {source} ambiguous_bare_names field must be a list
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/9be67e9673667b5e.
Report an issue: GitHub.