{"record":{"id":"fcff097427145c26","repo":"tobi/qmd","slug":"embedding-dimension-mismatch-existing-vectors-are","errorCode":null,"errorMessage":"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.","messagePattern":"Embedding dimension mismatch: existing vectors are (.+?)d but the current model produces (.+?)d\\. Run 'qmd embed -f' to re-embed with the new model\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/store.ts","lineNumber":1478,"sourceCode":"export function isSqliteVecAvailable(): boolean {\n  return _sqliteVecAvailable === true;\n}\n\nfunction ensureVecTableInternal(db: Database, dimensions: number): void {\n  if (!_sqliteVecAvailable) {\n    throw createSqliteVecUnavailableError(\n      _sqliteVecUnavailableReason ?? \"vector operations require a SQLite build with extension loading support\"\n    );\n  }\n  const tableInfo = db.prepare(`SELECT sql FROM sqlite_master WHERE type='table' AND name='vectors_vec'`).get() as { sql: string } | null;\n  if (tableInfo) {\n    const match = tableInfo.sql.match(/float\\[(\\d+)\\]/);\n    const hasHashSeq = tableInfo.sql.includes('hash_seq');\n    const hasCosine = tableInfo.sql.includes('distance_metric=cosine');\n    const existingDims = match?.[1] ? parseInt(match[1], 10) : null;\n    if (existingDims === dimensions && hasHashSeq && hasCosine) return;\n    if (existingDims !== null && existingDims !== dimensions) {\n      throw new Error(\n        `Embedding dimension mismatch: existing vectors are ${existingDims}d but the current model produces ${dimensions}d. ` +\n        `Run 'qmd embed -f' to re-embed with the new model.`\n      );\n    }\n    db.exec(\"DROP TABLE IF EXISTS vectors_vec\");\n  }\n  db.exec(`CREATE VIRTUAL TABLE vectors_vec USING vec0(hash_seq TEXT PRIMARY KEY, embedding float[${dimensions}] distance_metric=cosine)`);\n}\n\n// =============================================================================\n// Store Factory\n// =============================================================================\n\nexport type Store = {\n  db: Database;\n  dbPath: string;\n  /** Optional LlamaCpp instance for this store (overrides the global singleton) */\n  llm?: LlamaCpp;","sourceCodeStart":1460,"sourceCodeEnd":1496,"githubUrl":"https://github.com/tobi/qmd/blob/dbfd0b4736aeaf761d1a16ca8e424f071df8feb9/src/store.ts#L1460-L1496","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nqmd embed   # throws: dimension mismatch\n# after\nqmd embed -f   # re-embed all chunks with current model","handlingStrategy":"fallback","validationCode":"// before embedding, compare dims:\nconst info = db.prepare(\"SELECT sql FROM sqlite_master WHERE name='vectors_vec'\").get();\nconst dims = info?.sql?.match(/float\\[(\\d+)\\]/)?.[1];\nif (dims && +dims !== modelDims) await forceReembed();","typeGuard":null,"tryCatchPattern":"try { store.ensureVecTable(dims); } catch (e) { if (/dimension mismatch/.test((e as Error).message)) { await runEmbedForce(); return; } throw e; }","preventionTips":["Re-embed with -f immediately after changing embedding models","Pin the embedding model version per index","Keep separate indexes per model"],"tags":["embedding","sqlite-vec","dimension-mismatch","migration"],"backgroundTag":"embedding-dimension-mismatch","analyzedSha":"dbfd0b4736aeaf761d1a16ca8e424f071df8feb9","analyzedAt":"2026-08-28T18:07:46.628Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}