abhigyanpatwari/GitNexus · error

decision.error (embedding resume decision abort)

Error message

decision.error (embedding resume decision abort)

What it means

decideEmbeddingResume examined the stored embedding checkpoint against the current embedding identity and returned action 'abort'; the command throws with the decision's error message. This guards against resuming from a checkpoint that must not be reused (typically a foreign or unverified identity that cannot be safely migrated).

Solutions

  1. Read decision.error in the thrown message for the specific abort reason and follow it.
  2. Run `gitnexus analyze --embeddings --force` to discard the checkpoint and rebuild embeddings cleanly.
  3. Restore the embedding provider/model environment (API keys, env vars) to what the checkpoint was written with if you want resume instead.
  4. Remove/complete the interrupted run's checkpoint by re-running the interrupted command.

Example fix

// before
$ gitnexus embeddings-sync .   # abort per resume decision
// after
$ gitnexus analyze --embeddings --force
$ gitnexus embeddings-sync .
Defensive patterns

Strategy: try-catch

Validate before calling

// If you can read meta before syncing, refuse obvious abort cases yourself:
const meta = loadIndexMeta(repo);
if (meta?.embeddingCheckpoint?.kind === 'unverified-count') {
  await run('gitnexus analyze --embeddings --force'); // abort is the only safe path
}

Try / catch

try {
  await gitnexus.embeddingsSync(repo);
} catch (err) {
  // decision.error aborts are not transient — a rebuild is the fix
  await run('gitnexus analyze --embeddings --force');
  await gitnexus.embeddingsSync(repo);
}

Prevention

When it happens

Trigger: meta.embeddingCheckpoint exists and decideEmbeddingResume classifies it as abort — e.g. the checkpoint kind is one that always aborts (such as unverified-count) or the stored checkpoint state is unusable for resume.

Common situations: Switching embedding providers/models mid-way; an interrupted run recorded a checkpoint kind that cannot be resumed; a count could not be verified during the previous run.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15). Data as JSON: /api/errors/9d2f7947d998675d. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/cli/embeddings-sync.ts:82

    } catch {
      throw new Error(
        `The LadybugDB graph store at ${lbugPath} is missing. Run gitnexus analyze first.`,
      );
    }
    if (!lbugStat.isFile()) {
      throw new Error(
        `The LadybugDB graph store at ${lbugPath} is not a usable database file. Run gitnexus analyze first.`,
      );
    }

    const { resolveEmbeddingIdentity } = await import('../core/embeddings/embedding-identity.js');
    const identity = resolveEmbeddingIdentity();
    let forceReembedNodeIds: ReadonlySet<string> | undefined;
    let resumedFrom: EmbeddingCheckpoint | undefined;
    if (meta.embeddingCheckpoint) {
      const checkpoint = meta.embeddingCheckpoint;
      const decision = decideEmbeddingResume(checkpoint, identity);
      if (decision.action === 'abort') throw new Error(decision.error);
      const identityDiffers =
        checkpoint.provider !== identity.provider ||
        checkpoint.model !== identity.model ||
        checkpoint.dimensions !== identity.dimensions;
      // `abandon` on a foreign identity drops the pending set only. Existing
      // rows stay; sync would then embed the holes under the new identity and
      // mix vector spaces. Fail closed — rebuild via analyze.
      //
      // Every kind is gated, `unverified-count` included. Exempting it looked
      // safe because that kind only records "the count could not be read", but
      // `decideEmbeddingResume` returns `abandon` for it BEFORE comparing
      // identity, so the exemption was the only thing standing between a
      // foreign identity and a silently mixed table.
      if (identityDiffers) {
        throw new Error(
          `Cannot sync embeddings: the index checkpoint was written by ${checkpoint.model} ` +
            `(${checkpoint.provider}) at ${checkpoint.dimensions} dimensions, but this run ` +
            `resolves ${identity.model} (${identity.provider}) at ${identity.dimensions}. ` +

View on GitHub (pinned to ac9a4e9abd)