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

  1. Check the generated __init__.py's __all__ / _dynamic_imports (or call dir() on the module) to see the names the bundle actually exports.
  2. Import from the concrete submodule instead: `from lfx_helpers.<module> import Something`.
  3. 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

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


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/9be67e9673667b5e. Report an issue: GitHub.