Skip to content

bug(core): the embedding cache is keyed by the embedder's name, so it serves vectors of another model #1536

Closed

Description

@ajianaz

Problem

CachingEmbedder (embed/cache.rs) keys every entry on inner.name(), and the names are constants: "openai", "ollama", "embeddinggemma-q4"; FallbackEmbedder reports "fallback(onnx→cloud)". The key ignores the model, the dimensions and the endpoint. So switching text-embedding-3-small to -large, changing dims, or pointing at another endpoint serves the vector the previous configuration produced, silently, and a cloud vector produced through a fallback is cached under the primary's name. There is no dimension check on read.

Reproduced

A mock embeddings endpoint that records requests, same text, same UTEKE_HOME, [embedding] backend = "openai" with model = "model-a" and then model = "model-b": the second uteke remember never reaches the endpoint (one request in total) and stores the model-a vector.

Direction

The embedder owns an identity (what produced the vector: model, dimensions, endpoint) and the cache is keyed by it. Existing cache rows were written under the old key and simply stop being hit; the cache is a cache.

Behaviour impact

Local only, no wire change. After the upgrade the first embeddings are recomputed once. Recall results stop being wrong after a model switch.

Acceptance

  • A cache entry is never returned for a different model, dimension or endpoint (test with two fake embedders that differ only in one of them).
  • A vector read from the cache whose length is not the embedder's dimension is ignored.
  • A fallback result is not cached under the primary's identity.
  • Reproduced with the mock endpoint before and after (the second run reaches the endpoint).

Part of the embedding deepening epic.

Activity

  1. ajianaz commented on Oct 22, 2026

    @ajianaz
    CollaboratorAuthor

    Owner decision (2026-10-22): old cache rows are PURGED once, not left behind. The cache is a cache; rows written under the old key can never be hit again after the identity change and may hold vectors of the wrong model.

  2. ajianaz commented on Oct 22, 2026

    @ajianaz
    CollaboratorAuthor

    Fixed in #1544. The cache is keyed by an identity the embedder owns (backend, model, dimensions, endpoint hash; not the key), a vector of the wrong length is ignored, the cloud fallback's vectors are never cached, and the old rows are purged once. Reproduced before and after with the real binaries and a mock embeddings endpoint (model-b now reaches the endpoint).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingepic:memory-engineEpic: Memory engine core capabilitiespriority:highFix in next releasescope:coreCore engine work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions