{"record":{"id":"801774e993bf87c7","repo":"langchain-ai/langchain","slug":"vectorstore-destination-does-not-have-required-m","errorCode":null,"errorMessage":"Vectorstore {destination} does not have required method {method}","messagePattern":"Vectorstore (.+?) does not have required method (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/indexing/api.py","lineNumber":436,"sourceCode":"    if (cleanup in {\"incremental\", \"scoped_full\"}) and source_id_key is None:\n        msg = (\n            \"Source id key is required when cleanup mode is incremental or scoped_full.\"\n        )\n        raise ValueError(msg)\n\n    destination = vector_store  # Renaming internally for clarity\n\n    # If it's a vectorstore, let's check if it has the required methods.\n    if isinstance(destination, VectorStore):\n        # Check that the Vectorstore has required methods implemented\n        methods = [\"delete\", \"add_documents\"]\n\n        for method in methods:\n            if not hasattr(destination, method):\n                msg = (\n                    f\"Vectorstore {destination} does not have required method {method}\"\n                )\n                raise ValueError(msg)\n\n        if type(destination).delete == VectorStore.delete:\n            # Checking if the VectorStore has overridden the default delete method\n            # implementation which just raises a NotImplementedError\n            msg = \"Vectorstore has not implemented the delete method\"\n            raise ValueError(msg)\n    elif isinstance(destination, DocumentIndex):\n        pass\n    else:\n        msg = (  # type: ignore[unreachable]\n            f\"Vectorstore should be either a VectorStore or a DocumentIndex. \"\n            f\"Got {type(destination)}.\"\n        )\n        raise TypeError(msg)\n\n    if isinstance(docs_source, BaseLoader):\n        try:\n            doc_iterator = docs_source.lazy_load()","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/indexing/api.py#L418-L454","documentation":"Raised in `index()` during preflight checks when the destination `VectorStore` lacks a method required for indexing. Cleanup and upserts rely on `delete` and `add_documents`; if the object subclasses `VectorStore` but does not expose one of those methods (usually because a poorly-written subclass overrode or removed it, or a lazy proxy hides attributes), indexing is aborted with a `ValueError` naming the store and the missing method.","triggerScenarios":"Passing a custom VectorStore subclass that implements similarity search but not `add_documents` or `delete`; using `__getattr__`-based lazy proxies whose `hasattr` behavior is broken; partially-mocked stores in tests.","commonSituations":"Read-only vector store wrappers (search-only proxy over an external service); homegrown stores implementing only the retrieval interface; Mock objects without speccing.","solutions":["Implement the missing method on your store subclass (`add_documents` and `delete` are both mandatory for indexing).","Use `unittest.mock.create_autospec(VectorStore)` in tests so hasattr checks behave.","For search-only stores, do not use the indexing API — insert documents with the store's native path."],"exampleFix":"# before\nclass ReadOnlyStore(VectorStore):\n    # only similarity_search defined; no add_documents/delete\n    ...\n\n# after\nclass ReadOnlyStore(VectorStore):\n    def add_documents(self, documents, **kwargs):\n        self._client.upsert(...)\n        return [d.id for d in documents]\n\n    def delete(self, ids=None, **kwargs):\n        self._client.delete(ids)\n        return True","handlingStrategy":"type-guard","validationCode":"required = (\"add_documents\", \"delete\")\nmissing = [m for m in required if not hasattr(store, m)]\nif missing:\n    raise TypeError(f\"store lacks {missing}; cannot use indexing API\")\nindex(store, docs, rm, cleanup=\"full\")","typeGuard":"def supports_indexing(store) -> bool:\n    return all(hasattr(store, m) for m in (\"add_documents\", \"delete\"))","tryCatchPattern":null,"preventionTips":["Implement the full required interface on custom VectorStore subclasses.","Use create_autospec(VectorStore) for test doubles so hasattr preflights behave."],"tags":["indexing","vector-store","interface"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}