How to Fix 'embedding dimension mismatch in production' in LangGraph (TypeScript)

By Cyprian AaronsUpdated 2026-04-22
embedding-dimension-mismatch-in-productionlanggraphtypescript

When you see embedding dimension mismatch in production, it means the vector you’re sending to your store does not match the embedding size the index was created with. In LangGraph TypeScript apps, this usually shows up after a model swap, a retriever change, or a deployment where one service is still using an older embedding config.

The failure often appears deep in the stack, but the root cause is simple: your embedding model and your vector index are not aligned on dimension.

The Most Common Cause

The #1 cause is mixing embedding models across environments or deployments.

A common pattern is:

  • local dev uses one model
  • production uses another
  • the vector store was created with the old dimension
  • LangGraph starts writing or querying with the new dimension

Here’s the broken pattern:

BrokenFixed
Create index with one model, query with anotherUse one embedding model everywhere, or rebuild the index
// BROKEN: index was built with 1536-dim embeddings,
// but production now uses a different model.
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "langchain/vectorstores/memory";

const embeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-large", // different dim than your old index
});

const vectorStore = await MemoryVectorStore.fromTexts(
  ["policy renewal", "claims intake"],
  [{ id: "1" }, { id: "2" }],
  embeddings
);

// Later in LangGraph retrieval:
const results = await vectorStore.similaritySearch("renewal deadline", 4);
// FIXED: keep the same embedding model that matches the existing index,
// or recreate/migrate the index when changing models.
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "langchain/vectorstores/memory";

const embeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-small", // must match your stored index dimension
});

const vectorStore = await MemoryVectorStore.fromTexts(
  ["policy renewal", "claims intake"],
  [{ id: "1" }, { id: "2" }],
  embeddings
);

const results = await vectorStore.similaritySearch("renewal deadline", 4);

In production, this usually surfaces as something like:

  • Error: Embedding dimension mismatch
  • PineconeClientError: Vector dimension 1536 does not match the dimension of the index 3072
  • BadRequestError: expected vector of size X, got Y

If you changed models, don’t guess. Check the actual embedding size and compare it to your existing index.

Other Possible Causes

1. Your environment variables point to different models

This happens when EMBEDDING_MODEL differs between local and prod.

// BROKEN
const embeddings = new OpenAIEmbeddings({
  model: process.env.EMBEDDING_MODEL ?? "text-embedding-ada-002",
});
// FIXED: pin the model per environment and fail fast if missing.
const model = process.env.EMBEDDING_MODEL;
if (!model) throw new Error("EMBEDDING_MODEL is required");

const embeddings = new OpenAIEmbeddings({ model });

2. You recreated only part of the pipeline

Your graph may be using a new retriever, but your stored vectors are still old.

// BROKEN: retriever expects fresh embeddings, store contains legacy vectors.
const retriever = vectorStore.asRetriever();
// FIXED: rebuild or reindex before switching retrievers/models.
await reindexDocuments(documents, embeddings);
const retriever = vectorStore.asRetriever();

3. You are mixing providers with different dimensions

OpenAI, Cohere, Voyage, and local models do not share dimensions by default.

// BROKEN
const embeddings = provider === "openai"
  ? new OpenAIEmbeddings({ model: "text-embedding-3-large" })
  : new CohereEmbeddings({ model: "embed-english-v3.0" });
// FIXED: choose one provider per index.
const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });

4. Your stored vectors were truncated or transformed

If you serialize vectors through middleware, analytics code, or custom DB logic, they can get corrupted.

// BROKEN
const storedVector = embedding.slice(0, 128); // accidental truncation
await db.insert({ id, vector: storedVector });
// FIXED
await db.insert({ id, vector: embedding }); // preserve full length

How to Debug It

  1. Print the actual embedding length

    • Log the output of your embed call before inserting/querying.
    • Example:
    const vec = await embeddings.embedQuery("test");
    console.log("embedding length:", vec.length);
    
  2. Check the index dimension

    • Verify your Pinecone/Qdrant/Weaviate/pgvector schema.
    • Match it against vec.length, not what you think it should be.
  3. Trace which code path runs in production

    • Confirm env vars for EMBEDDING_MODEL, VECTOR_DB_URL, and any feature flags.
    • In LangGraph apps, different nodes can use different retrievers depending on state.
  4. Look for mixed data in the same collection

    • If some records were inserted with an old embedding model and others with a new one, queries may fail unpredictably.
    • Reindex everything into a fresh namespace or collection if needed.

Prevention

  • Pin one embedding model per index and treat it as part of schema design.
  • Add a startup check that compares embedQuery("ping").length against your configured store dimension.
  • When changing models, create a new namespace/index instead of silently reusing old vectors.

If you want this to stay stable in production, treat embedding dimension like a database column type. Once it changes without migration discipline, LangGraph will expose it fast.


Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides