langchain-ai/langchain · error · NotImplementedError

delete method must be implemented by subclass.

Error message

delete method must be implemented by subclass.

What it means

The base `VectorStore.delete` raises `NotImplementedError` because deletion is optional for vector store integrations. Subclasses that support removal must override it; otherwise callers get this explicit error rather than a silent no-op that would leave stale data.

Source

Thrown at libs/core/langchain_core/vectorstores/base.py:120

        logger.debug(
            "The embeddings property has not been implemented for %s",
            self.__class__.__name__,
        )
        return None

    def delete(self, ids: list[str] | None = None, **kwargs: Any) -> bool | None:
        """Delete by vector ID or other criteria.

        Args:
            ids: List of IDs to delete. If `None`, delete all.
            **kwargs: Other keyword arguments that subclasses might use.

        Returns:
            `True` if deletion is successful, `False` otherwise, `None` if not
                implemented.
        """
        msg = "delete method must be implemented by subclass."
        raise NotImplementedError(msg)

    def get_by_ids(self, ids: Sequence[str], /) -> list[Document]:
        """Get documents by their IDs.

        The returned documents are expected to have the ID field set to the ID of the
        document in the vector store.

        Fewer documents may be returned than requested if some IDs are not found or
        if there are duplicated IDs.

        Users should not assume that the order of the returned documents matches
        the order of the input IDs. Instead, users should rely on the ID field of the
        returned documents.

        This method should **NOT** raise exceptions if no documents are found for
        some IDs.

        Args:

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Check `type(store).delete is VectorStore.delete` before calling, and skip or branch to a store-specific deletion API.
  2. Implement `delete` in your custom subclass mapping `ids` to the backend's removal endpoint.
  3. For refresh workflows on stores without delete, re-ingest with stable explicit `ids` so upsert semantics replace content instead.

Example fix

# before
store.delete(ids=["doc1"])  # NotImplementedError

# after
if type(store).delete is not VectorStore.delete:
    store.delete(ids=["doc1"])
else:
    logger.warning("store %s does not support delete", type(store).__name__)
Defensive patterns

Strategy: type-guard

Validate before calling

from langchain_core.vectorstores import VectorStore

def can_delete(store: VectorStore) -> bool:
    return type(store).delete is not VectorStore.delete

Type guard

from langchain_core.vectorstores import VectorStore

def supports_delete(store: VectorStore) -> bool:
    """True if the store overrides the optional delete method."""
    return type(store).delete is not VectorStore.delete

Try / catch

try:
    store.delete(ids=stale_ids)
except NotImplementedError:
    # fall back to re-ingesting with the same ids (upsert semantics)
    store.add_texts(new_texts, new_metadatas, ids=stale_ids)

Prevention

When it happens

Trigger: Calling `vectorstore.delete(ids=[...])` on any store whose class does not override `delete` — including the base class itself and minimal custom subclasses.

Common situations: Generic cleanup pipelines (deleting documents by source or TTL) run against a store that never implemented deletion; assuming a standard-looking API exists on every integration; attempting document-refresh workflows (delete + re-add) on a read-optimized store.

Related errors


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