run-llama/llama_index · error · NotImplementedError

{self.__class__.__name__} does not provide lazy_load_data me

Error message

{self.__class__.__name__} does not provide lazy_load_data method currently

What it means

BaseReader declares lazy_load_data as the core data-loading primitive; the base implementation just raises NotImplementedError naming the subclass. load_data() in the base class delegates to lazy_load_data, so a reader that never implemented it fails at first load.

Source

Thrown at llama-index-core/llama_index/core/readers/base.py:24

    TYPE_CHECKING,
    Any,
    Dict,
    Iterable,
    List,
)

if TYPE_CHECKING:  # pragma: no cover
    from llama_index.core.bridge.langchain import Document as LCDocument  # type: ignore
from llama_index.core.bridge.pydantic import ConfigDict, Field
from llama_index.core.schema import BaseComponent, Document


class BaseReader(ABC):  # pragma: no cover
    """Utilities for loading data from a directory."""

    def lazy_load_data(self, *args: Any, **load_kwargs: Any) -> Iterable[Document]:
        """Load data from the input directory lazily."""
        raise NotImplementedError(
            f"{self.__class__.__name__} does not provide lazy_load_data method currently"
        )

    async def alazy_load_data(
        self, *args: Any, **load_kwargs: Any
    ) -> Iterable[Document]:
        """Load data from the input directory lazily."""
        # Threaded async - just calls the sync method with to_thread. Override in subclasses for real async implementations.
        return await asyncio.to_thread(self.lazy_load_data, *args, **load_kwargs)

    def load_data(self, *args: Any, **load_kwargs: Any) -> List[Document]:
        """Load data from the input directory."""
        return list(self.lazy_load_data(*args, **load_kwargs))

    async def aload_data(self, *args: Any, **load_kwargs: Any) -> List[Document]:
        """Load data from the input directory."""
        return await asyncio.to_thread(self.load_data, *args, **load_kwargs)

View on GitHub (pinned to afd0fef371)

Solutions

  1. Implement lazy_load_data(self, *args, **kwargs) -> Iterable[Document] in your subclass
  2. Alternatively override load_data() directly if lazy iteration is not needed, though implementing lazy_load_data is the convention
  3. Check you instantiated the intended reader class, not BaseReader or a bare skeleton

Example fix

// before
class MyReader(BaseReader):
    def load_data(self, input_dir: str) -> list[Document]:
        ...  # lazy_load_data never defined; base load_data path still raises

// after
class MyReader(BaseReader):
    def lazy_load_data(self, input_dir: str) -> Iterable[Document]:
        for path in Path(input_dir).glob("*.txt"):
            yield Document(text=path.read_text())
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.readers.base import BaseReader

def reader_implements_lazy_load(reader: BaseReader) -> bool:
    return type(reader).lazy_load_data is not BaseReader.lazy_load_data

assert reader_implements_lazy_load(reader), \
    f"{type(reader).__name__} never implemented lazy_load_data"

Type guard

def is_loadable_reader(reader) -> bool:
    """True when the subclass actually implements lazy_load_data."""
    from llama_index.core.readers.base import BaseReader
    return (
        isinstance(reader, BaseReader)
        and type(reader).lazy_load_data is not BaseReader.lazy_load_data
    )

Prevention

When it happens

Trigger: Calling load_data() or lazy_load_data() on a custom BaseReader subclass that did not override lazy_load_data (or on a reader instance created via the abstract base directly).

Common situations: Writing a custom reader and overriding load_data but not lazy_load_data (the base load_data wraps lazy_load_data), or copy-pasting a reader skeleton without filling in the loader.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/0196581080ea4220. Report an issue: GitHub.