{"record":{"id":"a883c703458e54ef","repo":"langchain-ai/langchain","slug":"self-class-name-does-not-implement-lazy","errorCode":null,"errorMessage":"{self.__class__.__name__} does not implement lazy_load()","messagePattern":"(.+?) does not implement lazy_load\\(\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/document_loaders/base.py","lineNumber":100,"sourceCode":"\n            text_splitter_: TextSplitter = RecursiveCharacterTextSplitter()\n        else:\n            text_splitter_ = text_splitter\n        docs = self.load()\n        return text_splitter_.split_documents(docs)\n\n    # Attention: This method will be upgraded into an abstractmethod once it's\n    #            implemented in all the existing subclasses.\n    def lazy_load(self) -> Iterator[Document]:\n        \"\"\"A lazy loader for `Document`.\n\n        Yields:\n            The `Document` objects.\n        \"\"\"\n        if type(self).load != BaseLoader.load:\n            return iter(self.load())\n        msg = f\"{self.__class__.__name__} does not implement lazy_load()\"\n        raise NotImplementedError(msg)\n\n    async def alazy_load(self) -> AsyncIterator[Document]:\n        \"\"\"A lazy loader for `Document`.\n\n        Yields:\n            The `Document` objects.\n        \"\"\"\n        iterator = await run_in_executor(None, self.lazy_load)\n        done = object()\n        while True:\n            doc = await run_in_executor(None, next, iterator, done)\n            if doc is done:\n                break\n            yield doc  # type: ignore[misc]\n\n\nclass BaseBlobParser(ABC):\n    \"\"\"Abstract interface for blob parsers.","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/document_loaders/base.py#L82-L118","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Implement `lazy_load(self) -> Iterator[Document]` on your subclass (preferred, enables lazy `load` and default `alazy_load`)","Or implement `load(self) -> list[Document]` — the base `lazy_load` detects an overridden `load` and delegates","Check for typos/signature drift: the dispatch check is `type(self).load != BaseLoader.load`","Add a smoke test: `assert list(MyLoader().lazy_load())`"],"exampleFix":"# before\nclass MyLoader(BaseLoader):\n    def load_docs(self): ...  # wrong name\n\n# after\nclass MyLoader(BaseLoader):\n    def lazy_load(self) -> Iterator[Document]:\n        yield Document(page_content=\"...\", metadata={\"src\": \"x\"})","handlingStrategy":"type-guard","validationCode":"from langchain_core.document_loaders import BaseLoader\n\ndef loader_can_load(loader: BaseLoader) -> bool:\n    implements_lazy = type(loader).lazy_load is not BaseLoader.lazy_load\n    implements_load = type(loader).load is not BaseLoader.load\n    return implements_lazy or implements_load","typeGuard":"from langchain_core.document_loaders import BaseLoader\n\ndef is_loadable(loader: BaseLoader) -> bool:\n    \"\"\"True if the loader implements lazy_load or load.\"\"\"\n    return (\n        type(loader).lazy_load is not BaseLoader.lazy_load\n        or type(loader).load is not BaseLoader.load\n    )","tryCatchPattern":null,"preventionTips":["Implement lazy_load in every custom loader (preferred over load)","Add a smoke test that lists documents from each custom loader","Beware method renames during refactors — the base detects overrides by identity"],"tags":["document-loader","interface","not-implemented"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}