Skip to content

bug(server): switching embedding provider silently drops writes due to vector dimension mismatch #4985

Description

@g-kartik

Description

When the embedding provider is switched (e.g. from OpenAI to Gemini) via the dashboard or POST /configure, the pgvector collection retains the original provider's vector dimension. Subsequent memory writes silently fail — the API returns a success response with a memory ID, but nothing is persisted to the database.

Steps to Reproduce

  1. Start the server with make bootstrap (defaults to OpenAI embedder — creates memories table with vector(1536))
  2. Switch the embedder to Gemini (gemini-embedding-001) via the dashboard Configuration page
  3. POST /memories with a message
  4. Observe the success response:
{
    "results": [
        {
            "id": "f88e7d7d-b882-4975-b9cf-7f945e244eb3",
            "memory": "My name is John and I am a software engineer",
            "event": "ADD"
        }
    ]
}
  1. GET /memories?user_id=...{"results": []}
  2. Query postgres directly:
SELECT COUNT(*) FROM memories;
-- Returns: 0

Root Cause

There are three layers to this bug:

Layer 1 — embedding_model_dims defaults to 1536 and is never inferred from the embedder

The pgvector config hardcodes embedding_model_dims = 1536 as its default:

# mem0/configs/vector_stores/pgvector.py
embedding_model_dims: Optional[int] = Field(1536, description="Dimensions of the embedding model")

This default is OpenAI-specific and silently wrong for every other provider. Critically, Memory.__init__ instantiates self.embedding_model before self.vector_store and already has the correct dimension available (self.embedding_model.config.embedding_dims = 768 for Gemini), but never uses it to set vector_store.config.embedding_model_dims. The information is present but ignored.

Layer 2 — Table created with wrong dimensions on every restart

Even after manually dropping the memories table and restarting, it is immediately recreated with vector(1536) because the pgvector config default (Layer 1) kicks in before any override can correct it.

Layer 3 — Dimension mismatch fails silently

Inserting a 768-dim vector into a vector(1536) column raises no exception to the caller. The API returns 200 with a memory ID as if the write succeeded, but nothing is persisted.

Expected Behaviour

  • Memory.__init__ should auto-set vector_store.config.embedding_model_dims from self.embedding_model.config.embedding_dims when not explicitly provided
  • Or at minimum, validate that the two match and raise a clear error if they don't
  • The dimension mismatch on insert should propagate as an error, not be swallowed silently

Actual Behaviour

  • memories table is created with vector(1536) regardless of the configured embedder
  • POST /memories returns 200 with a valid-looking memory ID
  • The memory is never actually stored in postgres
  • GET /memories returns empty results
  • No error or warning anywhere in the logs

Impact

This is a silent data loss bug. Users believe their memories are being stored (success response + memory ID), but they are not. The only way to diagnose it is to directly query the postgres table and inspect vector dimensions — not at all obvious.

This affects every non-OpenAI embedding provider (Gemini, Cohere, etc.) that uses a dimension other than 1536.

Workaround

Explicitly pass embedding_model_dims in the vector store config (not the embedder config) via POST /configure:

{
  "embedder": {"provider": "gemini", "config": {"model": "models/gemini-embedding-001"}},
  "vector_store": {"provider": "pgvector", "config": {"embedding_model_dims": 768}}
}

Then drop and recreate the memories table:

DROP TABLE IF EXISTS memories;
DROP TABLE IF EXISTS mem0migrations;

Then restart the container.

Environment

  • Self-hosted server via docker compose
  • OpenAI embedder → Gemini gemini-embedding-001 (1536 → 768 dims)
  • Reproduced on: 2026-04-27

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1-highBlocks significant use case, high demandacceptedA maintainer has agreed to this change. Required before a PR is reviewed.bugSomething isn't workingsdk-pythonPython SDK specific

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions