{"record":{"id":"3d32e65ae0ce1775","repo":"abhigyanpatwari/GitNexus","slug":"cannot-resume-embedding-checkpoint-it-uses-chec","errorCode":null,"errorMessage":"Cannot resume embedding checkpoint: it uses ${checkpoint.model} at ${checkpoint.dimensions} dimensions, but this run resolves ${identity.model} at ${identity.dimensions}. Restore the matching embedding configuration or pass --drop-embeddings to rebuild without it.","messagePattern":"Cannot resume embedding checkpoint: it uses (.+?) at (.+?) dimensions, but this run resolves (.+?) at (.+?)\\. Restore the matching embedding configuration or pass --drop-embeddings to rebuild without it\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/run-analyze.ts","lineNumber":1315,"sourceCode":"  let resumedEmbeddingCheckpoint: EmbeddingCheckpoint | undefined;\n  if (existingMeta?.embeddingCheckpoint) {\n    const checkpoint = existingMeta.embeddingCheckpoint;\n    // The verdict itself lives in embedding-checkpoint.ts, shared with\n    // `POST /api/embed` — two readers of one marker must not be able to\n    // disagree about what it means.\n    //\n    // The identity stays LAZY, as it has to: the flag and retry-budget verdicts\n    // short-circuit before one is needed, and resolving it means importing an\n    // embeddings module (#2370 — none loads unless a run actually needs one).\n    // `decideEmbeddingResume` asks for it by aborting on `undefined`, which is\n    // the only abort it can reach without one.\n    let decision = decideEmbeddingResume(checkpoint, undefined, options);\n    if (decision.action === 'abort') {\n      const { resolveEmbeddingIdentity } = await import('./embeddings/embedding-identity.js');\n      embeddingIdentityForRun = resolveEmbeddingIdentity();\n      decision = decideEmbeddingResume(checkpoint, embeddingIdentityForRun, options);\n    }\n    if (decision.action === 'abort') throw new Error(decision.error);\n    log(decision.log);\n    if (options.dropEmbeddings) {\n      // --drop-embeddings has always implied a rebuild here; the decision only\n      // covers the marker.\n      options = { ...options, force: true };\n    }\n    if (decision.action === 'resume') {\n      resumeEmbeddingCheckpoint = true;\n      pendingEmbeddingNodeIds = new Set(decision.pendingNodeIds);\n      resumedEmbeddingCheckpoint = decision.resumedFrom;\n    }\n  }\n\n  // ── Crash recovery: dirty flag forces full rebuild ────────────────\n  // If the previous incremental run set incrementalInProgress and didn't\n  // clear it, the on-disk index may be in a half-state. Cheapest path\n  // back to a known-good index is to wipe + rebuild from scratch.\n  if (existingMeta?.incrementalInProgress) {","sourceCodeStart":1297,"sourceCodeEnd":1333,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/run-analyze.ts#L1297-L1333","documentation":"Thrown by `decideEmbeddingResume` when the checkpoint's model or dimensions differ from the current run's resolved identity (provider matches), and the checkpoint kind is `'interrupted'`. Even with the same provider, a different model or dimensionality produces incompatible vectors — resuming would write rows into a vector space that doesn't match the existing ones, corrupting semantic search.","triggerScenarios":"`decideEmbeddingResume` with a resolved identity where `checkpoint.model !== identity.model` or `checkpoint.dimensions !== identity.dimensions` (provider matches), kind is `'interrupted'`, and no `--force`/`--drop-embeddings` flag.","commonSituations":"Switched from `text-embedding-3-small` (1536 dims) to `text-embedding-3-large` (3072 dims) under the same OpenAI provider, or changed `GITNEXUS_EMBEDDING_MODEL` between runs, leaving an interrupted checkpoint from the old model.","solutions":["Restore the original `GITNEXUS_EMBEDDING_MODEL` (and any dimension-affecting config) to match the checkpoint, then re-run `gitnexus analyze`.","If the model change is intentional, run `gitnexus analyze --drop-embeddings` to discard the old checkpoint and rebuild under the new model.","Run `gitnexus analyze --force` for a full rebuild."],"exampleFix":"// before\n// checkpoint model=text-embedding-ada-002, current model=text-embedding-3-small\ngitnexus analyze\n// error: ...uses text-embedding-ada-002 at 1536 dimensions, but this run resolves...\n// after (intentional model upgrade)\ngitnexus analyze --drop-embeddings","handlingStrategy":"validation","validationCode":"// Before analyze, compare checkpoint model/dimensions with current env:\nimport { loadMeta } from './storage/repo-manager.js';\nimport { checkpointKind } from './embedding-checkpoint.js';\nconst meta = await loadMeta(metaDir);\nconst cp = meta?.embeddingCheckpoint;\nif (cp && checkpointKind(cp) === 'interrupted') {\n  const currentModel = process.env.GITNEXUS_EMBEDDING_MODEL;\n  if (currentModel && cp.model !== currentModel) {\n    console.error(`Model mismatch: checkpoint=${cp.model}, current=${currentModel}.`);\n    console.error('Restore matching config or pass --drop-embeddings.');\n    process.exit(1);\n  }\n}","typeGuard":"import { checkpointKind } from './embedding-checkpoint.js';\nconst isModelMismatchFatal = (\n  checkpoint: EmbeddingCheckpoint,\n  currentModel: string,\n  currentDims: number,\n): boolean =>\n  checkpointKind(checkpoint) === 'interrupted' &&\n  (checkpoint.model !== currentModel || checkpoint.dimensions !== currentDims);","tryCatchPattern":"try {\n  await runAnalyze(options);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('it uses') && err.message.includes('dimensions')) {\n    console.error('Restore the original embedding model or run `gitnexus analyze --drop-embeddings`.');\n  }\n  throw err;\n}","preventionTips":["Pin `GITNEXUS_EMBEDDING_MODEL` in config to avoid silent model drift across environments.","When upgrading embedding models, always pass `--drop-embeddings` to avoid vector-space incompatibility."],"tags":["embeddings","checkpoint","resume","configuration","model-mismatch"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}