abhigyanpatwari/GitNexus · error · Error

Repository metadata is missing; run gitnexus analyze first

Error message

Repository metadata is missing; run gitnexus analyze first

What it means

POST /api/embed loads repository metadata from the resolved repo's storagePath (loadMeta); when it gets null the embedding pipeline cannot run, because embeddings are computed against an existing GitNexus index. The error tells you the storage directory has no metadata — the repo was never analyzed by this server (or its data is gone).

Source

Thrown at gitnexus/src/server/api.ts:1769

          }
        }, EMBED_TIMEOUT_MS);

        // Run embedding pipeline asynchronously
        (async () => {
          // Set inside withLbugDb, read after it closes (#2790).
          let partialRunError: string | undefined;
          let partialRunDetail: AnalyzeJobPartialOutcome | undefined;
          try {
            const lbugPath = path.join(entry.storagePath, 'lbug');
            await withLbugDb(lbugPath, async () => {
              const { runEmbeddingPipeline } =
                await import('../core/embeddings/embedding-pipeline.js');
              const { resolveEmbeddingIdentity } =
                await import('../core/embeddings/embedding-identity.js');
              const embeddingIdentity = resolveEmbeddingIdentity();
              let embeddingMeta = await loadMeta(entry.storagePath);
              if (!embeddingMeta) {
                throw new Error('Repository metadata is missing; run gitnexus analyze first');
              }
              const priorCheckpoint = embeddingMeta.embeddingCheckpoint;
              // The SAME decision the CLI's resume gate makes
              // (core/embedding-checkpoint.ts). This route used to hard-throw on
              // any identity mismatch and ignore `attempts` entirely, so a
              // `'partial'` marker written by `gitnexus analyze` and resumed
              // here hit exactly the permanent wedge `kind` exists to remove:
              // two readers of one record disagreeing about the rule it encodes.
              // No `force`/`--drop-embeddings` equivalent exists on this route,
              // so the flag options go unset and `'discard'` is unreachable —
              // it is folded into the abandon arm rather than given an invented
              // flag. `maxAttempts` is left to the shared default.
              const resume = priorCheckpoint
                ? decideEmbeddingResume(priorCheckpoint, embeddingIdentity)
                : undefined;
              if (resume?.action === 'abort') throw new Error(resume.error);
              if (resume?.action === 'abandon' || resume?.action === 'discard') {
                logger.warn({ repo: entry.name }, resume.log);

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Run a full analysis first — POST /api/analyze (url or path) or `gitnexus analyze` on the machine — then retry /api/embed
  2. Verify the repo's storagePath on disk actually contains the metadata/index files
  3. Check GITNEXUS_HOME consistency between the process that indexed and the process serving /api/embed
  4. If the volume was wiped, re-index and re-embed from scratch

Example fix

# before
curl -X POST http://localhost:4747/api/embed?repo=myrepo # 500: metadata missing

# after
curl -X POST http://localhost:4747/api/analyze -H 'content-type: application/json' -d '{"url":"https://github.com/user/myrepo.git"}'
# wait for job completion, then
curl -X POST http://localhost:4747/api/embed?repo=myrepo
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight: the repo must already have an index on this server
async function repoIsIndexed(repo, fetchEntry) {
  const entry = await fetchEntry(repo); // registry/storage resolution
  return Boolean(entry && entry.storagePath && entry.hasIndex);
}

Type guard

function isAnalyzedRepoEntry(entry) {
  return Boolean(entry && entry.storagePath && entry.indexedAt);
}

Try / catch

try { await runEmbeddings(repo); }
catch (e) {
  if (/Repository metadata is missing/.test(String(e.message))) {
    await runFullAnalyze(repo); // establish the index first
    return runEmbeddings(repo); // then retry once
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /api/embed?repo=X where X is registered but its storagePath lacks the metadata file: embedding was requested before any analyze ran, the index/data was deleted, or GITNEXUS_HOME now points somewhere else than when the repo was indexed.

Common situations: Trying to embed immediately after registering a repo; a Docker container recreated with an empty /data/gitnexus volume (GITNEXUS_HOME) while the registry survived; moving/copying the data dir without metadata; pointing GITNEXUS_HOME at a fresh path so resolveRepo returns a stale entry.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20). Data as JSON: /api/errors/b79ee6837fbf4f46. Report an issue: GitHub.