langchain-ai/langchain · error · NotImplementedError

{self.__class__.__name__} does not implement lazy_load()

Error message

{self.__class__.__name__} does not implement lazy_load()

What it means

`BaseLoader.lazy_load` (document_loaders/base.py) raises `NotImplementedError` when a subclass implements neither `lazy_load` nor `load`. The base provides default `load` (built on `lazy_load`) and `lazy_load` (built on `load`); if neither is overridden the cycle bottoms out here. The comment notes it will become an abstractmethod once all subclasses comply.

Source

Thrown at libs/core/langchain_core/document_loaders/base.py:100

            text_splitter_: TextSplitter = RecursiveCharacterTextSplitter()
        else:
            text_splitter_ = text_splitter
        docs = self.load()
        return text_splitter_.split_documents(docs)

    # Attention: This method will be upgraded into an abstractmethod once it's
    #            implemented in all the existing subclasses.
    def lazy_load(self) -> Iterator[Document]:
        """A lazy loader for `Document`.

        Yields:
            The `Document` objects.
        """
        if type(self).load != BaseLoader.load:
            return iter(self.load())
        msg = f"{self.__class__.__name__} does not implement lazy_load()"
        raise NotImplementedError(msg)

    async def alazy_load(self) -> AsyncIterator[Document]:
        """A lazy loader for `Document`.

        Yields:
            The `Document` objects.
        """
        iterator = await run_in_executor(None, self.lazy_load)
        done = object()
        while True:
            doc = await run_in_executor(None, next, iterator, done)
            if doc is done:
                break
            yield doc  # type: ignore[misc]


class BaseBlobParser(ABC):
    """Abstract interface for blob parsers.

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Implement `lazy_load(self) -> Iterator[Document]` on your subclass (preferred, enables lazy `load` and default `alazy_load`)
  2. Or implement `load(self) -> list[Document]` — the base `lazy_load` detects an overridden `load` and delegates
  3. Check for typos/signature drift: the dispatch check is `type(self).load != BaseLoader.load`
  4. Add a smoke test: `assert list(MyLoader().lazy_load())`

Example fix

# before
class MyLoader(BaseLoader):
    def load_docs(self): ...  # wrong name

# after
class MyLoader(BaseLoader):
    def lazy_load(self) -> Iterator[Document]:
        yield Document(page_content="...", metadata={"src": "x"})
Defensive patterns

Strategy: type-guard

Validate before calling

from langchain_core.document_loaders import BaseLoader

def loader_can_load(loader: BaseLoader) -> bool:
    implements_lazy = type(loader).lazy_load is not BaseLoader.lazy_load
    implements_load = type(loader).load is not BaseLoader.load
    return implements_lazy or implements_load

Type guard

from langchain_core.document_loaders import BaseLoader

def is_loadable(loader: BaseLoader) -> bool:
    """True if the loader implements lazy_load or load."""
    return (
        type(loader).lazy_load is not BaseLoader.lazy_load
        or type(loader).load is not BaseLoader.load
    )

Prevention

When it happens

Trigger: Defining a `BaseLoader` subclass that only overrides e.g. `alazy_load` or adds helpers, then calling `list(loader.lazy_load())` or `loader.load()`; instantiating `BaseLoader` directly; refactors that renamed `lazy_load` to something else.

Common situations: Writing custom document loaders and forgetting the one required method; subclassing a loader whose upstream `load` override was removed during upgrade; mock loaders in tests.

Related errors


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