BerriAI/litellm · error · AttributeError

HTTP handlers lazy import: unknown attribute {name!r}

Error message

HTTP handlers lazy import: unknown attribute {name!r}

What it means

The HTTP-handlers lazy-import handler is a small factory: for 'module_level_client' it builds a sync HTTPHandler with the module's request_timeout and caches it (and, per the sibling code, an async variant similarly). Any other name routed here raises AttributeError 'HTTP handlers lazy import: unknown attribute <name>'. Only the pre-declared module-level HTTP client entries are supported.

Source

Thrown at litellm/_lazy_imports.py:447

            params=params,
        )

        # Cache it so we don't create it again
        _globals["module_level_aclient"] = async_client
        return async_client

    if name == "module_level_client":
        # Create a sync HTTP client
        from litellm.llms.custom_httpx.http_handler import HTTPHandler

        timeout = _globals.get("request_timeout")
        sync_client: Final = HTTPHandler(timeout=timeout)

        # Cache it
        _globals["module_level_client"] = sync_client
        return sync_client

    raise AttributeError(f"HTTP handlers lazy import: unknown attribute {name!r}")

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Use the exact supported names — check the handler body in litellm/_lazy_imports.py for the current whitelist (e.g. module_level_client and its async counterpart).
  2. Prefer configuring timeouts via documented API (e.g. request_timeout / per-call timeout) over touching module-level clients.
  3. In tests, patch the concrete client class (litellm.llms.custom_httpx.http_handler.HTTPHandler) rather than guessing top-level names.
  4. After a litellm upgrade, re-verify internal names you depend on — these handlers are internal surface and can change.

Example fix

# before
client = litellm.http_module_client  # AttributeError: HTTP handlers lazy import: unknown attribute ...

# after
client = litellm.module_level_client  # cached sync HTTPHandler built with module request_timeout
Defensive patterns

Strategy: type-guard

Validate before calling

ALLOWED = {'module_level_client', 'module_level_aclient'}  # verify against installed _lazy_imports.py
if name not in ALLOWED:
    raise AttributeError(f'{name!r} not built by the HTTP handlers factory')

Type guard

import litellm

def http_client_attr(name: str):
    try:
        return getattr(litellm, name)
    except AttributeError as e:
        if 'HTTP handlers lazy import' in str(e):
            return None
        raise

Try / catch

try:
    client = getattr(litellm, 'module_level_client')
except AttributeError as e:
    if 'HTTP handlers lazy import' in str(e):
        client = None  # unsupported name; check whitelist in _lazy_imports.py
    else:
        raise

Prevention

When it happens

Trigger: Accessing litellm.module_level_client with a typo, or asking for names like 'http_handler', 'aclient', or 'module_level_aclient'-style guesses that the handler does not recognize; automated attribute-walking (pickle/copy of the module, mock.patch autospec) can also trip it.

Common situations: Test suites that mock litellm's shared HTTP clients and reference them by guessed names; code wanting to set timeouts by replacing the module-level client; refactors across litellm versions renaming these internals.

Related errors


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