abhigyanpatwari/GitNexus · error · Error
Cannot resume embedding checkpoint: no embedding identity wa
Error message
Cannot resume embedding checkpoint: no embedding identity was resolved.
What it means
Thrown when `decideEmbeddingResume` returns `{ action: 'abort', error: 'Cannot resume embedding checkpoint: no embedding identity was resolved.' }` and the re-invocation after resolving the identity still aborts. The embedding identity (model, dimensions, provider) is resolved lazily because importing the embeddings module is expensive. When `resolveEmbeddingIdentity()` returns undefined — no embedding configuration is available — the function cannot determine whether the checkpoint's pending nodes belong to the same vector space, so it fails closed to prevent vector-space mixing.
Source
Thrown at gitnexus/src/core/run-analyze.ts:1315
let resumedEmbeddingCheckpoint: EmbeddingCheckpoint | undefined;
if (existingMeta?.embeddingCheckpoint) {
const checkpoint = existingMeta.embeddingCheckpoint;
// The verdict itself lives in embedding-checkpoint.ts, shared with
// `POST /api/embed` — two readers of one marker must not be able to
// disagree about what it means.
//
// The identity stays LAZY, as it has to: the flag and retry-budget verdicts
// short-circuit before one is needed, and resolving it means importing an
// embeddings module (#2370 — none loads unless a run actually needs one).
// `decideEmbeddingResume` asks for it by aborting on `undefined`, which is
// the only abort it can reach without one.
let decision = decideEmbeddingResume(checkpoint, undefined, options);
if (decision.action === 'abort') {
const { resolveEmbeddingIdentity } = await import('./embeddings/embedding-identity.js');
embeddingIdentityForRun = resolveEmbeddingIdentity();
decision = decideEmbeddingResume(checkpoint, embeddingIdentityForRun, options);
}
if (decision.action === 'abort') throw new Error(decision.error);
log(decision.log);
if (options.dropEmbeddings) {
// --drop-embeddings has always implied a rebuild here; the decision only
// covers the marker.
options = { ...options, force: true };
}
if (decision.action === 'resume') {
resumeEmbeddingCheckpoint = true;
pendingEmbeddingNodeIds = new Set(decision.pendingNodeIds);
resumedEmbeddingCheckpoint = decision.resumedFrom;
}
}
// ── Crash recovery: dirty flag forces full rebuild ────────────────
// If the previous incremental run set incrementalInProgress and didn't
// clear it, the on-disk index may be in a half-state. Cheapest path
// back to a known-good index is to wipe + rebuild from scratch.
if (existingMeta?.incrementalInProgress) {View on GitHub (pinned to d540b00184)
Solutions
- Set the embedding environment variables (`GITNEXUS_EMBEDDING_URL`, `GITNEXUS_EMBEDDING_MODEL`) to match the configuration used when the checkpoint was created, then re-run `gitnexus analyze`.
- If you no longer need embeddings, run `gitnexus analyze --drop-embeddings` to discard the checkpoint and index without embeddings.
- Run `gitnexus analyze --force` to rebuild from scratch (this discards the checkpoint via the force path).
Example fix
// before gitnexus analyze // error: Cannot resume embedding checkpoint: no embedding identity was resolved. // after export GITNEXUS_EMBEDDING_URL=https://api.openai.com/v1 gitnexus analyze // or: gitnexus analyze --drop-embeddings
Defensive patterns
Strategy: validation
Validate before calling
// Before analyze, check if a checkpoint exists and whether an embedding identity can be resolved:
import { loadMeta } from './storage/repo-manager.js';
const meta = await loadMeta(metaDir);
if (meta?.embeddingCheckpoint) {
// Ensure embedding env vars are set if the checkpoint is 'interrupted' or 'partial'
if (!process.env.GITNEXUS_EMBEDDING_URL) {
console.error('An embedding checkpoint exists but GITNEXUS_EMBEDDING_URL is not set.');
console.error('Set the matching config or run `gitnexus analyze --drop-embeddings`.');
process.exit(1);
}
} Type guard
import { checkpointKind } from './embedding-checkpoint.js';
const needsEmbeddingIdentity = (checkpoint: EmbeddingCheckpoint): boolean => {
const kind = checkpointKind(checkpoint);
return kind === 'interrupted' || kind === 'partial';
}; Try / catch
try {
await runAnalyze(options);
} catch (err) {
if (err instanceof Error && err.message.includes('no embedding identity was resolved')) {
console.error('Set GITNEXUS_EMBEDDING_URL/MODEL to match the checkpoint, or run --drop-embeddings.');
}
throw err;
} Prevention
- Always set `GITNEXUS_EMBEDDING_URL` and `GITNEXUS_EMBEDDING_MODEL` consistently across environments that share an index.
- Use `--drop-embeddings` when you intentionally run without embeddings to avoid leaving unresolvable checkpoints.
When it happens
Trigger: An `embeddingCheckpoint` exists in `meta.json` whose kind is `'interrupted'` or `'partial'` (not `'unverified-count'`, which skips the identity gate), and `resolveEmbeddingIdentity()` returns undefined because no embedding endpoint/model is configured in the current environment.
Common situations: A CI job or hook ran `gitnexus analyze --embeddings` with `GITNEXUS_EMBEDDING_URL` set, crashed, and left an 'interrupted' checkpoint; a subsequent run in an environment without the embedding env vars hits the identity-resolution failure.
Related errors
- Cannot resume embedding checkpoint: the embedding provider c
- Cannot resume embedding checkpoint: it uses ${checkpoint.mod
- GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${p
- Embedding generation completed without persisted embeddings.
- ${source} must be true/false or a non-negative integer (node
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/9366211c91bd158b.
Report an issue: GitHub.