run-llama/llama_index · error · NotImplementedError

delete_nodes not implemented

Error message

delete_nodes not implemented

What it means

`BaseVectorStore.delete_nodes()` follows the same pattern as get_nodes: declared on the base class with a default body that raises NotImplementedError, overridden only by stores that support node-level deletion. Many integrations only implement document-level `delete(ref_doc_id)`. The async `adelete_nodes()` delegates synchronously, so it raises the same error.

Source

Thrown at llama-index-core/llama_index/core/vector_stores/types.py:402

        """
        Delete nodes using with ref_doc_id."""

    async def adelete(self, ref_doc_id: str, **delete_kwargs: Any) -> None:
        """
        Delete nodes using with ref_doc_id.
        NOTE: this is not implemented for all vector stores. If not implemented,
        it will just call delete synchronously.
        """
        self.delete(ref_doc_id, **delete_kwargs)

    def delete_nodes(
        self,
        node_ids: Optional[List[str]] = None,
        filters: Optional[MetadataFilters] = None,
        **delete_kwargs: Any,
    ) -> None:
        """Delete nodes from vector store."""
        raise NotImplementedError("delete_nodes not implemented")

    async def adelete_nodes(
        self,
        node_ids: Optional[List[str]] = None,
        filters: Optional[MetadataFilters] = None,
        **delete_kwargs: Any,
    ) -> None:
        """Asynchronously delete nodes from vector store."""
        self.delete_nodes(node_ids, filters)

    def clear(self) -> None:
        """Clear all nodes from configured vector store."""
        raise NotImplementedError("clear not implemented")

    async def aclear(self) -> None:
        """Asynchronously clear all nodes from configured vector store."""
        self.clear()

View on GitHub (pinned to afd0fef371)

Solutions

  1. Detect support before calling: `type(store).delete_nodes is not BaseVectorStore.delete_nodes`.
  2. Fall back to document-level deletion: `store.delete(ref_doc_id)` for each affected document, then re-add.
  3. Use a store integration that implements delete_nodes if per-node deletion is required.
  4. Wrap calls in try/except NotImplementedError for multi-backend tooling.

Example fix

# before
store.delete_nodes(node_ids=stale_ids)  # NotImplementedError

# after
from llama_index.core.vector_stores import BaseVectorStore
if type(store).delete_nodes is not BaseVectorStore.delete_nodes:
    store.delete_nodes(node_ids=stale_ids)
else:
    for doc_id in stale_ref_doc_ids:
        store.delete(doc_id)
Defensive patterns

Strategy: fallback

Validate before calling

from llama_index.core.vector_stores import BaseVectorStore

def supports_delete_nodes(store) -> bool:
    return type(store).delete_nodes is not BaseVectorStore.delete_nodes

Try / catch

try:
    store.delete_nodes(node_ids=stale_ids)
except NotImplementedError:
    for ref in affected_ref_doc_ids:
        store.delete(ref)

Prevention

When it happens

Trigger: Calling `store.delete_nodes(node_ids=[...])` or `store.delete_nodes(filters=...)` on a store integration without the override; code that assumes fine-grained node deletion exists everywhere (e.g. partial re-indexing pipelines).

Common situations: Building incremental ingestion that prunes stale chunks by node id; switching backends from a store that supports node deletion (Qdrant, Chroma) to one that does not; cleanup scripts run against the default SimpleVectorStore-backed index.

Related errors


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