langchain-ai/langchain · error · TypeError

Vectorstore should be either a VectorStore or a DocumentInde

Error message

Vectorstore should be either a VectorStore or a DocumentIndex. Got {type(vector_store)}.

What it means

Raised by `_delete` in `langchain_core.indexing.api` when the object passed as the indexing destination is neither a `VectorStore` nor a `DocumentIndex` instance. The indexer needs one of those two interfaces to write and delete documents; anything else (a retriever, a plain object, a Mock) is a `TypeError`. Marked unreachable by type checkers because the signature restricts the type, but duck-typed callers can hit it.

Source

Thrown at libs/core/langchain_core/indexing/api.py:277

        TypeError: If the `vector_store` is neither a `VectorStore` nor a
            `DocumentIndex`.
    """
    if isinstance(vector_store, VectorStore):
        delete_ok = vector_store.delete(ids)
        if delete_ok is not None and delete_ok is False:
            msg = "The delete operation to VectorStore failed."
            raise IndexingException(msg)
    elif isinstance(vector_store, DocumentIndex):
        delete_response = vector_store.delete(ids)
        if "num_failed" in delete_response and delete_response["num_failed"] > 0:
            msg = "The delete operation to DocumentIndex failed."
            raise IndexingException(msg)
    else:
        msg = (  # type: ignore[unreachable]
            f"Vectorstore should be either a VectorStore or a DocumentIndex. "
            f"Got {type(vector_store)}."
        )
        raise TypeError(msg)


# PUBLIC API


class IndexingResult(TypedDict):
    """Return a detailed a breakdown of the result of the indexing operation."""

    num_added: int
    """Number of added documents."""
    num_updated: int
    """Number of updated documents because they were not up to date."""
    num_deleted: int
    """Number of deleted documents."""
    num_skipped: int
    """Number of skipped documents because they were already up to date."""

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Pass the actual `VectorStore` instance (e.g. the `Chroma`/`FAISS`/`PGVector` object) to `index()`.
  2. If you have a custom store, subclass `langchain_core.vectorstores.base.VectorStore` and implement `add_documents`/`delete` (plus similarity APIs as applicable).
  3. For docstore-style targets, implement/extend the `DocumentIndex` interface instead.

Example fix

# before
index(my_retriever, docs, record_manager)  # retriever is not a VectorStore

# after
index(my_retriever.vectorstore, docs, record_manager)
Defensive patterns

Strategy: type-guard

Validate before calling

from langchain_core.vectorstores import VectorStore
from langchain_core.document_loaders import DocumentIndex  # or langchain_core.indexing

if not isinstance(destination, (VectorStore, DocumentIndex)):
    raise TypeError("index() requires a VectorStore or DocumentIndex")

Type guard

def is_indexing_target(obj) -> bool:
    from langchain_core.vectorstores import VectorStore
    return isinstance(obj, VectorStore) or getattr(obj, "delete", None) is not None and hasattr(obj, "add_documents")

Prevention

When it happens

Trigger: Calling `index(retriever, docs, rm)` (an arbitrary retriever is not a VectorStore); passing a wrapper/proxy object that does not subclass VectorStore or register as DocumentIndex; passing a Mock in tests.

Common situations: Assuming any retriever-like object works with the indexing API; wrapping a vector store in a custom class without inheriting from `VectorStore`; test doubles replacing the store.

Related errors


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