microsoft/semantic-kernel · error · ValueError

The vector store must have an embedding generator.

Error message

The vector store must have an embedding generator.

What it means

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.

Source

Thrown at python/samples/concepts/caching/semantic_caching.py:42

@vectorstoremodel(collection_name=COLLECTION_NAME)
@dataclass
class CacheRecord:
    result: Annotated[str, VectorStoreField("data", is_full_text_indexed=True)]
    prompt: Annotated[str | None, VectorStoreField("vector", dimensions=1536)] = None
    id: Annotated[str, VectorStoreField("key")] = field(default_factory=lambda: str(uuid4()))


# Define the filters, one for caching the results and one for using the cache.
class PromptCacheFilter:
    """A filter to cache the results of the prompt rendering and function invocation."""

    def __init__(
        self,
        vector_store: VectorStore,
        score_threshold: float = 0.2,
    ):
        if vector_store.embedding_generator is None:
            raise ValueError("The vector store must have an embedding generator.")
        self.vector_store = vector_store
        self.collection: VectorStoreCollection[str, CacheRecord] = vector_store.get_collection(record_type=CacheRecord)
        self.score_threshold = score_threshold

    async def on_prompt_render(
        self, context: PromptRenderContext, next: Callable[[PromptRenderContext], Awaitable[None]]
    ):
        """Filter to cache the rendered prompt and the result of the function.

        It uses the score threshold to determine if the result should be cached.
        The direction of the comparison is based on the default distance metric for
        the in memory vector store, which is cosine distance, so the closer to 0 the
        closer the match.
        """
        await next(context)
        await self.collection.ensure_collection_exists()
        results = await self.collection.search(context.rendered_prompt, vector_property_name="prompt", top=1)
        async for result in results.results:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Pass an embedding generator when creating the vector store (e.g. InMemoryVectorStore(embedding_generator=<your embeddings service>).
  2. Ensure the embedding service is constructed before the vector store and assigned to its embedding_generator.
  3. Use a store/connector that natively carries an embedding generator if you do not want to wire one manually.

Example fix

# before
vector_store = InMemoryVectorStore()
# PromptCacheFilter(vector_store=vector_store)  # raises: no embedding generator
# after
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding
embeddings = OpenAITextEmbedding(service_id="ada", ai_model_id="text-embedding-3-small")
vector_store = InMemoryVectorStore(embedding_generator=embeddings)
filter = PromptCacheFilter(vector_store=vector_store)
Defensive patterns

Strategy: validation

Validate before calling

def ensure_embedding_generator(vector_store):
    if vector_store.embedding_generator is None:
        raise ValueError(
            "Vector store has no embedding_generator; semantic caching cannot work. "
            "Pass embedding_generator=<embedding service> when constructing the store."
        )
    return vector_store

Type guard

from typing import Protocol
class HasEmbeddingGenerator(Protocol):
    embedding_generator: object

def has_embedding_generator(store) -> bool:
    return getattr(store, "embedding_generator", None) is not None

Try / catch

try:
    cache_filter = PromptCacheFilter(vector_store=store)
except ValueError as e:
    # construct the store with an embedding service, then retry
    print(e)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/bcd5ecc152618bce. Report an issue: GitHub.