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
- Run a full analysis first — POST /api/analyze (url or path) or `gitnexus analyze` on the machine — then retry /api/embed
- Verify the repo's storagePath on disk actually contains the metadata/index files
- Check GITNEXUS_HOME consistency between the process that indexed and the process serving /api/embed
- 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
- Always run analyze to completion before /api/embed on a repo
- Keep GITNEXUS_HOME (and the Docker /data/gitnexus volume) stable between indexing and embedding
- Monitor the repo list for entries whose storagePath no longer exists on disk
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
- analyze --watch does not support ${unsupported.map(([name])
- ${name} must be a positive integer, got "${value}"
- embedding device must be one of auto, dml, cuda, cpu, wasm;
- Local semantic embeddings are unavailable on macOS Intel (da
- Local semantic embeddings are unavailable: the optional embe
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20).
Data as JSON: /api/errors/b79ee6837fbf4f46.
Report an issue: GitHub.