langchain-ai/langchain · error · AttributeError

module '{package!r}' has no attribute {attr_name!r}

Error message

module '{package!r}' has no attribute {attr_name!r}

What it means

Raised by `import_attr`-style lazy-import helper in langchain_core._import_utils when it tries to import `package.attr_name` as a submodule (module_name is `"__module__"` or None) and Python raises ModuleNotFoundError — i.e. the package has no submodule by that name, so the requested attribute cannot exist. It is re-raised as AttributeError to mimic normal `module.attr` access failing on a missing attribute.

Source

Thrown at libs/core/langchain_core/_import_utils.py:33

        attr_name: The name of the attribute to import.
        module_name: The name of the module to import from.

            If `None`, the attribute is imported from the package itself.
        package: The name of the package where the module is located.

    Raises:
        ImportError: If the module cannot be found.
        AttributeError: If the attribute does not exist in the module or package.

    Returns:
        The imported attribute.
    """
    if module_name == "__module__" or module_name is None:
        try:
            result = import_module(f".{attr_name}", package=package)
        except ModuleNotFoundError:
            msg = f"module '{package!r}' has no attribute {attr_name!r}"
            raise AttributeError(msg) from None
    else:
        try:
            module = import_module(f".{module_name}", package=package)
        except ModuleNotFoundError as err:
            msg = f"module '{package!r}.{module_name!r}' not found ({err})"
            raise ImportError(msg) from None
        result = getattr(module, attr_name)
    return result

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Check the exact spelling/casing against the module's `__init__.py` exports or the API reference for your installed version.
  2. If the symbol moved, import from its new location (changelogs and DeprecationWarning messages usually name the new path).
  3. If it lives in a partner package, install that package (`uv add langchain-openai` etc.) instead of expecting it in core.
  4. Pin/upgrade to the version whose API surface you coded against (`uv sync` to honor the lockfile).

Example fix

# before
from langchain_core.messages import HummanMessage

# after
from langchain_core.messages import HumanMessage
Defensive patterns

Strategy: try-catch

Validate before calling

import importlib.util

def submodule_exists(package: str, attr: str) -> bool:
    return importlib.util.find_spec(f"{package}.{attr}") is not None

Type guard

def is_exported(module, name: str) -> bool:
    return getattr(module, "__all__", None) is None or name in module.__all__

Try / catch

try:
    from langchain_core.messages import HumanMessage
except AttributeError:
    # wrong name or wrong version: check __all__ of the installed version
    import langchain_core.messages as m
    raise SystemExit(f"not exported here: {sorted(m.__all__)}")

Prevention

When it happens

Trigger: A lazy module `__getattr__` (e.g. `langchain_core.some_pkg.__getattr__('MissingThing')`) dispatches to `import_attr(package='langchain_core.some_pkg', attr_name='MissingThing')` and there is no `langchain_core/some_pkg/missing_thing.py` (or `missing_thing` submodule of any casing). Also triggered by `importlib.import_module('pkg.Missing')` style typos routed through this helper.

Common situations: Typo in a public API name (`from langchain_core.messages import HummanMessage`), using a name that exists only in a newer/older langchain-core version, or referencing an integration class that lives in a separate partner package that isn't installed. Because it surfaces as AttributeError, users often misread it as a missing re-export rather than a wrong name.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/6d08839215b07c45. Report an issue: GitHub.