How to Fix 'embedding dimension mismatch' in LlamaIndex (TypeScript)
When LlamaIndex throws embedding dimension mismatch, it means the vector you are trying to store or compare does not have the same length as the vector dimension expected by your vector store or index. In TypeScript, this usually shows up when you change embedding models, reuse an old index, or mix documents embedded with different models.
The failure often appears during insert, query, or upsert calls, and the underlying vector DB will complain with errors like:
- •
Error: Vector dimension mismatch - •
Expected dimension 1536, got 3072 - •
PineconeBadRequestError: Vector dimension 3072 does not match the dimension of the index 1536
The Most Common Cause
The #1 cause is using one embedding model to build the index and a different embedding model to query it later.
This happens a lot when you switch from one OpenAI embedding model to another, or when your local code defaults to a different model than your production ingestion job.
Broken vs fixed pattern
| Broken | Fixed |
|---|---|
| Build index with one embedder, query with another | Use the same embedder everywhere |
| Store vectors in an index created for 1536 dims, then query with 3072-dim vectors | Recreate the index or keep dimensions aligned |
// ❌ Broken: ingest and query use different embedding dimensions
import { Settings, VectorStoreIndex } from "llamaindex";
import { OpenAIEmbedding } from "@llamaindex/openai";
async function main() {
// Ingestion used text-embedding-3-large somewhere else (3072 dims)
Settings.embedModel = new OpenAIEmbedding({
model: "text-embedding-3-small", // 1536 dims
});
const index = await VectorStoreIndex.fromDocuments(docs);
// Later in another process:
Settings.embedModel = new OpenAIEmbedding({
model: "text-embedding-3-large", // 3072 dims
});
const queryEngine = index.asQueryEngine();
const result = await queryEngine.query({ query: "What is the policy?" });
}
// ✅ Fixed: same embedding model for ingestion and querying
import { Settings, VectorStoreIndex } from "llamaindex";
import { OpenAIEmbedding } from "@llamaindex/openai";
const embedModel = new OpenAIEmbedding({
model: "text-embedding-3-small",
});
async function main() {
Settings.embedModel = embedModel;
const index = await VectorStoreIndex.fromDocuments(docs);
// Keep the same model for queries
Settings.embedModel = embedModel;
const queryEngine = index.asQueryEngine();
const result = await queryEngine.query({ query: "What is the policy?" });
}
If you are using a persistent vector database like Pinecone, this mismatch usually means your collection/index was created with one dimension and your current embedding model produces another.
Other Possible Causes
1) Reusing an old vector index after changing models
If you changed embedding models but kept the same namespace/collection/table, old vectors remain in the previous dimension.
// Existing Pinecone index was created for 1536-dim vectors
const pineconeIndexName = "support-docs";
// New embedder outputs 3072 dims
Settings.embedModel = new OpenAIEmbedding({
model: "text-embedding-3-large",
});
// Upsert fails here
await storageContext.vectorStore.add(nodes);
Fix it by recreating the vector index or migrating all stored vectors.
// Recreate the store with matching dimensions before re-ingesting
await deleteOldIndex("support-docs");
await createIndex({ name: "support-docs", dimension: 3072 });
2) Mixing embeddings from multiple providers
A common mistake is ingesting with OpenAI embeddings and querying with Cohere or Hugging Face embeddings.
// ❌ Mixed providers
Settings.embedModel = new OpenAIEmbedding({ model: "text-embedding-3-small" });
// ingestion...
Settings.embedModel = new CohereEmbedding({
model: "embed-multilingual-v3.0",
});
// querying...
Each provider has its own output size. Keep provider and model consistent across ingestion and retrieval.
3) Your vector store dimension was configured manually and is wrong
Some stores require you to set a fixed dimension at creation time.
// ❌ Wrong dimension for current embedder
await pinecone.createIndex({
name: "claims-index",
dimension: 1536,
});
// But your embedder now returns 3072-dim vectors
Settings.embedModel = new OpenAIEmbedding({
model: "text-embedding-3-large",
});
Match the store dimension to the actual embedding output. For text-embedding-3-small, use 1536. For text-embedding-3-large, use 3072.
4) Cached nodes were generated with a stale embedder
If you cache serialized nodes or precomputed embeddings, those cached values can outlive config changes.
// Old cached node embeddings on disk
const cachedNodes = JSON.parse(fs.readFileSync("./nodes.json", "utf8"));
// New runtime embedder differs from cached embeddings
Settings.embedModel = new OpenAIEmbedding({
model: "text-embedding-3-large",
});
Delete stale caches and regenerate embeddings whenever you change models.
How to Debug It
- •
Print the active embedding model before ingestion and before querying
- •Log
Settings.embedModeland confirm both sides use the same class and model name. - •If they differ, you found the bug.
- •Log
- •
Check the expected vector size of your embedder
- •Verify output dimensions from docs or by inspecting one generated vector.
- •Example:
const emb = await Settings.embedModel.getTextEmbedding("hello"); console.log(emb.length);
- •
Inspect your vector store schema
- •Pinecone, Qdrant, Weaviate, and similar systems all store a fixed dimensionality.
- •If your current embedder returns a different length than that schema, queries will fail.
- •
Delete one document and re-ingest it end-to-end
- •Start with a clean namespace/collection.
- •If that works, your issue is stale data or mixed historical embeddings, not your code path.
Prevention
- •Use one shared embedding config module for both ingestion and querying.
- •Pin the embedding model name explicitly; do not rely on defaults.
- •When changing models, create a new vector namespace/index instead of overwriting old data.
- •Add a startup check that compares one sample embedding length against your vector store dimension before processing real data.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
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