BerriAI/litellm · error · AttributeError

{category} lazy import: unknown attribute {name!r}

Error message

{category} lazy import: unknown attribute {name!r}

What it means

The generic lazy-import engine in litellm/_lazy_imports.py resolves module attributes via explicit import maps (name -> (module_path, attr_name)). When a requested name is absent from the map for that category, step 1 fails fast with AttributeError '<category> lazy import: unknown attribute <name>'. This is the internal backstop behind litellm's top-level lazy imports — the name is simply not registered for lazy loading.

Source

Thrown at litellm/_lazy_imports.py:233

    Steps:
    1. Check if the name exists in the import map (if not, raise error)
    2. Check if we've already imported it (if yes, return cached value)
    3. Look up where to find it (module_path and attr_name from the map)
    4. Import the module (Python caches this automatically)
    5. Get the attribute from the module
    6. Cache it in _globals so we don't import again
    7. Return it

    Args:
        name: The attribute name someone is trying to access (e.g., "ModelResponse")
        import_map: Dictionary telling us where to find each attribute
                   Format: {"ModelResponse": (".utils", "ModelResponse")}
        category: Just for error messages (e.g., "Utils", "Cost calculator")
    """
    # Step 1: Make sure this attribute exists in our map
    if name not in import_map:
        raise AttributeError(f"{category} lazy import: unknown attribute {name!r}")

    # Step 2: Get the cache (where we store imported things)
    _globals: Final = get_litellm_globals()

    # Step 3: If we've already imported it, just return the cached version
    if name in _globals:
        return _globals[name]

    # Step 4: Look up where to find this attribute
    # The map tells us: (module_path, attribute_name)
    # Example: (".utils", "ModelResponse") means "look in .utils module, get ModelResponse"
    module_path, attr_name = import_map[name]

    # Step 5: Import the module
    # Python automatically caches modules in sys.modules, so calling this twice is fast
    # If module_path starts with ".", it's a relative import (needs package="litellm")
    # Otherwise it's an absolute import (like "litellm.caching.caching")
    if module_path.startswith("."):

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Search the installed package for the symbol: rg '<Name>' $(python -c 'import litellm, os; print(os.path.dirname(litellm.__file__))') to find its real home.
  2. Import from the owning submodule directly rather than relying on top-level lazy resolution.
  3. Align versions: pin the litellm version whose lazy map contains the attribute (check the map dictionaries in litellm/_lazy_imports.py).
  4. Verify you're importing the real package (pip show litellm; no local litellm.py shadowing).

Example fix

# before
from litellm import SomeType  # AttributeError: ... lazy import: unknown attribute 'SomeType'

# after: import from the module that defines it
from litellm.types.utils import SomeType
Defensive patterns

Strategy: type-guard

Validate before calling

import litellm, os, subprocess
root = os.path.dirname(litellm.__file__)
subprocess.run(['grep', '-rn', f'def {name}', root])  # locate real definition

Type guard

import litellm

def safe_litellm_attr(name: str, default=None):
    try:
        return getattr(litellm, name)
    except AttributeError:
        return default

Try / catch

try:
    value = getattr(litellm, name)
except AttributeError as e:
    if 'lazy import: unknown attribute' in str(e):
        # name not registered for lazy loading in this version
        return None
    raise

Prevention

When it happens

Trigger: Accessing a top-level litellm attribute that the lazy maps don't cover in the installed version — e.g. a removed constant, a misremembered class name, or something that only exists on a different version's map. The category in the message (e.g. 'Cost calculator', 'LLM provider logic') tells you which map was consulted.

Common situations: Upgrading/downgrading litellm where import maps were regenerated and a name dropped; user code doing getattr with computed names; pickling or introspection walking every attribute; shadowing a local file named litellm so a stale module is imported.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/c5945dfaefd7a3d8. Report an issue: GitHub.