tobi/qmd · critical · Error
Embedding dimension mismatch: existing vectors are ${existin
Error message
Embedding dimension mismatch: existing vectors are ${existingDims}d but the current model produces ${dimensions}d. Run 'qmd embed -f' to re-embed with the new model. What it means
ensureVecTable() detected that the existing sqlite-vec virtual table `vectors_vec` was built with a different embedding dimensionality than the current embedding model produces. Vectors of differing dimensions cannot coexist, so the store aborts instead of silently corrupting search.
Source
Thrown at src/store.ts:1478
export function isSqliteVecAvailable(): boolean {
return _sqliteVecAvailable === true;
}
function ensureVecTableInternal(db: Database, dimensions: number): void {
if (!_sqliteVecAvailable) {
throw createSqliteVecUnavailableError(
_sqliteVecUnavailableReason ?? "vector operations require a SQLite build with extension loading support"
);
}
const tableInfo = db.prepare(`SELECT sql FROM sqlite_master WHERE type='table' AND name='vectors_vec'`).get() as { sql: string } | null;
if (tableInfo) {
const match = tableInfo.sql.match(/float\[(\d+)\]/);
const hasHashSeq = tableInfo.sql.includes('hash_seq');
const hasCosine = tableInfo.sql.includes('distance_metric=cosine');
const existingDims = match?.[1] ? parseInt(match[1], 10) : null;
if (existingDims === dimensions && hasHashSeq && hasCosine) return;
if (existingDims !== null && existingDims !== dimensions) {
throw new Error(
`Embedding dimension mismatch: existing vectors are ${existingDims}d but the current model produces ${dimensions}d. ` +
`Run 'qmd embed -f' to re-embed with the new model.`
);
}
db.exec("DROP TABLE IF EXISTS vectors_vec");
}
db.exec(`CREATE VIRTUAL TABLE vectors_vec USING vec0(hash_seq TEXT PRIMARY KEY, embedding float[${dimensions}] distance_metric=cosine)`);
}
// =============================================================================
// Store Factory
// =============================================================================
export type Store = {
db: Database;
dbPath: string;
/** Optional LlamaCpp instance for this store (overrides the global singleton) */
llm?: LlamaCpp;View on GitHub (pinned to dbfd0b4736)
Solutions
- Run `qmd embed -f` to force re-embedding everything with the current model
- Or delete/recreate the index (remove ~/.cache/qmd/index.sqlite or the collection) and re-index
- Keep one index per embedding model; re-embed immediately after any model change
Example fix
# before qmd embed # throws: dimension mismatch # after qmd embed -f # re-embed all chunks with current model
Defensive patterns
Strategy: fallback
Validate before calling
// before embedding, compare dims:
const info = db.prepare("SELECT sql FROM sqlite_master WHERE name='vectors_vec'").get();
const dims = info?.sql?.match(/float\[(\d+)\]/)?.[1];
if (dims && +dims !== modelDims) await forceReembed(); Try / catch
try { store.ensureVecTable(dims); } catch (e) { if (/dimension mismatch/.test((e as Error).message)) { await runEmbedForce(); return; } throw e; } Prevention
- Re-embed with -f immediately after changing embedding models
- Pin the embedding model version per index
- Keep separate indexes per model
When it happens
Trigger: Switching embedding models (e.g. to embeddinggemma with a different dim count) and then embedding into an existing index whose vectors_vec table declares float[oldDims]; detected via the table DDL's float[N] match.
Common situations: Upgrading qmd to a version bundling a new embedding model; pointing qmd at an old index.sqlite created with a previous model; experimentation with custom GGUF embedding models.
Related errors
- sqlite-vec extension is unavailable. ${hint}
- Failed to create any embedding context
- LLM operations are disabled in CI (set CI=true)
- ${name} must be a positive integer
- Failed to get embedding dimensions from first chunk
AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28).
Data as JSON: /api/errors/fcff097427145c26.
Report an issue: GitHub.