{"record":{"id":"bcd5ecc152618bce","repo":"microsoft/semantic-kernel","slug":"the-vector-store-must-have-an-embedding-generator","errorCode":null,"errorMessage":"The vector store must have an embedding generator.","messagePattern":"The vector store must have an embedding generator\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/samples/concepts/caching/semantic_caching.py","lineNumber":42,"sourceCode":"@vectorstoremodel(collection_name=COLLECTION_NAME)\n@dataclass\nclass CacheRecord:\n    result: Annotated[str, VectorStoreField(\"data\", is_full_text_indexed=True)]\n    prompt: Annotated[str | None, VectorStoreField(\"vector\", dimensions=1536)] = None\n    id: Annotated[str, VectorStoreField(\"key\")] = field(default_factory=lambda: str(uuid4()))\n\n\n# Define the filters, one for caching the results and one for using the cache.\nclass PromptCacheFilter:\n    \"\"\"A filter to cache the results of the prompt rendering and function invocation.\"\"\"\n\n    def __init__(\n        self,\n        vector_store: VectorStore,\n        score_threshold: float = 0.2,\n    ):\n        if vector_store.embedding_generator is None:\n            raise ValueError(\"The vector store must have an embedding generator.\")\n        self.vector_store = vector_store\n        self.collection: VectorStoreCollection[str, CacheRecord] = vector_store.get_collection(record_type=CacheRecord)\n        self.score_threshold = score_threshold\n\n    async def on_prompt_render(\n        self, context: PromptRenderContext, next: Callable[[PromptRenderContext], Awaitable[None]]\n    ):\n        \"\"\"Filter to cache the rendered prompt and the result of the function.\n\n        It uses the score threshold to determine if the result should be cached.\n        The direction of the comparison is based on the default distance metric for\n        the in memory vector store, which is cosine distance, so the closer to 0 the\n        closer the match.\n        \"\"\"\n        await next(context)\n        await self.collection.ensure_collection_exists()\n        results = await self.collection.search(context.rendered_prompt, vector_property_name=\"prompt\", top=1)\n        async for result in results.results:","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/samples/concepts/caching/semantic_caching.py#L24-L60","documentation":"ValueError raised by the sample PromptCacheFilter.__init__ when the supplied VectorStore has no embedding_generator. Semantic caching needs to embed the prompt into a vector to compare against cached entries by similarity, so a vector store without an embedding generator cannot perform the cache lookup the filter relies on. The constructor fails fast so later requests do not silently miss the cache.","triggerScenarios":"Constructing PromptCacheFilter(vector_store=vs) where vs.embedding_generator is None - e.g. an InMemoryVectorStore created without an embedding service, or a store whose embedding generator was not injected.","commonSituations":"Following the semantic-caching sample but forgetting to add an embedding service to the vector store; using a vector store configured for raw record storage only; or initializing the store before the embedding service is available.","solutions":["Pass an embedding generator when creating the vector store (e.g. InMemoryVectorStore(embedding_generator=<your embeddings service>).","Ensure the embedding service is constructed before the vector store and assigned to its embedding_generator.","Use a store/connector that natively carries an embedding generator if you do not want to wire one manually."],"exampleFix":"# before\nvector_store = InMemoryVectorStore()\n# PromptCacheFilter(vector_store=vector_store)  # raises: no embedding generator\n# after\nfrom semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding\nembeddings = OpenAITextEmbedding(service_id=\"ada\", ai_model_id=\"text-embedding-3-small\")\nvector_store = InMemoryVectorStore(embedding_generator=embeddings)\nfilter = PromptCacheFilter(vector_store=vector_store)","handlingStrategy":"validation","validationCode":"def ensure_embedding_generator(vector_store):\n    if vector_store.embedding_generator is None:\n        raise ValueError(\n            \"Vector store has no embedding_generator; semantic caching cannot work. \"\n            \"Pass embedding_generator=<embedding service> when constructing the store.\"\n        )\n    return vector_store","typeGuard":"from typing import Protocol\nclass HasEmbeddingGenerator(Protocol):\n    embedding_generator: object\n\ndef has_embedding_generator(store) -> bool:\n    return getattr(store, \"embedding_generator\", None) is not None","tryCatchPattern":"try:\n    cache_filter = PromptCacheFilter(vector_store=store)\nexcept ValueError as e:\n    # construct the store with an embedding service, then retry\n    print(e)","preventionTips":["Always construct the vector store with an embedding service for semantic caching.","Build the embedding service before the store so you can inject it.","Assert store.embedding_generator is not None before building the filter."],"tags":["python","sample","semantic-cache","vector-store","embeddings","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}