{"record":{"id":"f023c4673cc7dcf4","repo":"abhigyanpatwari/GitNexus","slug":"resume-error","errorCode":null,"errorMessage":"${resume.error}","messagePattern":"\\$\\{resume\\.error\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":2033,"sourceCode":"                const embeddingIdentity = resolveEmbeddingIdentity();\n                if (!embeddingMeta) {\n                  throw new Error('Repository metadata is missing; run gitnexus analyze first');\n                }\n                const priorCheckpoint = embeddingMeta.embeddingCheckpoint;\n                // The SAME decision the CLI's resume gate makes\n                // (core/embedding-checkpoint.ts). This route used to hard-throw on\n                // any identity mismatch and ignore `attempts` entirely, so a\n                // `'partial'` marker written by `gitnexus analyze` and resumed\n                // here hit exactly the permanent wedge `kind` exists to remove:\n                // two readers of one record disagreeing about the rule it encodes.\n                // No `force`/`--drop-embeddings` equivalent exists on this route,\n                // so the flag options go unset and `'discard'` is unreachable —\n                // it is folded into the abandon arm rather than given an invented\n                // flag. `maxAttempts` is left to the shared default.\n                const resume = priorCheckpoint\n                  ? decideEmbeddingResume(priorCheckpoint, embeddingIdentity)\n                  : undefined;\n                if (resume?.action === 'abort') throw new Error(resume.error);\n                if (resume?.action === 'abandon' || resume?.action === 'discard') {\n                  logger.warn({ repo: entry.name }, resume.log);\n                }\n                const forceReembedNodeIds: ReadonlySet<string> =\n                  resume?.action === 'resume' ? resume.pendingNodeIds : new Set<string>();\n                const saveEmbeddingCheckpoint = async (\n                  checkpoint: {\n                    nodesProcessed: number;\n                    totalNodes: number;\n                    chunksProcessed: number;\n                  },\n                  pendingNodeIds: string[],\n                  embeddings?: PersistedEmbeddingCount,\n                ): Promise<void> => {\n                  // tri-review NEW-2: re-read immediately before writing (mirrors\n                  // the pattern in run-analyze.ts's --repair-fts stamp) instead of\n                  // spreading the stale `embeddingMeta` snapshot captured once at\n                  // job start. This job can run up to EMBED_TIMEOUT_MS (30 min);","sourceCodeStart":2015,"sourceCodeEnd":2051,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/server/api.ts#L2015-L2051","documentation":"During an embedding pass, `decideEmbeddingResume` inspects the prior run's embedding checkpoint. When its verdict is `action: 'abort'` — the checkpoint cannot be safely resumed (e.g. embedding identity/provider mismatch where resuming would mix vector spaces, or a fail-closed condition) — the API throws with the decision's pre-computed, user-facing `resume.error` message rather than silently discarding or mixing embeddings.","triggerScenarios":"`POST /api/embed` (or the embeddings sync) finds a `priorCheckpoint` whose kind requires the current run's embedding identity and the identity does not match (different model/provider/dimensions), so `decideEmbeddingResume` returns `{action:'abort', error}` and `throw new Error(resume.error)` fires at gitnexus/src/server/api.ts:2033.","commonSituations":"Switching embedding providers or models between runs and re-embedding the same repo; changing embedding dimensions in config; a checkpoint written by a different GitNexus version with an incompatible identity; re-pointing the repo at a different embedding endpoint.","solutions":["Read `resume.error` — it names the identity mismatch; align the current embedding provider/model/dimensions with the checkpoint.","Re-run embedding with the force/discard path (`--embeddings --force` or the API equivalent) to discard the checkpoint and rebuild from scratch.","Run `gitnexus analyze --drop-embeddings` to clear the stale checkpoint, then re-embed with the desired identity.","Verify the checkpoint's stored identity against your current config before re-triggering the embed endpoint."],"exampleFix":"// before: provider changed but old checkpoint forces abort\nPOST /api/embed  ->  Error: checkpoint was written with provider 'openai/text-embedding-3-small'; current run uses 'ollama/...'\n// after: discard the incompatible checkpoint first\n$ gitnexus analyze --embeddings --force","handlingStrategy":"try-catch","validationCode":"// compare the checkpoint's stored identity with the current run identity before embedding\nimport { decideEmbeddingResume } from './core/embedding-checkpoint';\nconst decision = priorCheckpoint ? decideEmbeddingResume(priorCheckpoint, currentIdentity) : undefined;\nif (decision?.action === 'abort') {\n  // handle up front: force/discard or realign provider config\n}","typeGuard":"const isAbort = (d) => d?.action === 'abort' && typeof d.error === 'string';","tryCatchPattern":"try {\n  await embedRepo(entry);\n} catch (e) {\n  if (isEmbeddingIdentityAbort(e)) {\n    logger.warn('Embedding identity mismatch — discarding checkpoint and re-embedding from scratch');\n    await embedRepo(entry, { force: true });\n  } else throw e;\n}","preventionTips":["Keep embedding provider/model/dimension config stable for a repo between runs.","When intentionally switching providers, always pass the force/discard option to clear the old checkpoint.","Inspect `gitnexus status` checkpoint metadata before re-embedding after a config change.","Store embedding identity in infra-as-code so drift between environments is caught early."],"tags":["embeddings","checkpoint","resume","identity-mismatch"],"backgroundTag":"invalid-state-transition","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-15T23:29:44.066Z","contentChangedAt":"2026-09-15T23:29:44.066Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}