{"record":{"id":"5422340be62e5155","repo":"abhigyanpatwari/GitNexus","slug":"analyze-finalization-not-visible-after-timeout-co","errorCode":null,"errorMessage":"analyze finalization not visible after timeout; completing job anyway","messagePattern":"analyze finalization not visible after timeout; completing job anyway","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/server/analyze-launch.ts","lineNumber":117,"sourceCode":"      return (\n        lbugStat.mtimeMs >= jobStartMs &&\n        metaStat.mtimeMs >= jobStartMs &&\n        ['lbug.wal', 'lbug.shadow', 'lbug.wal.checkpoint'].every(\n          (f) => !existsSync(path.join(storagePath, f)),\n        )\n      );\n    } catch {\n      return false; // not written yet\n    }\n  };\n  const deadline = Date.now() + FINALIZE_SETTLE_TIMEOUT_MS;\n  for (;;) {\n    // Re-resolved each round: the worker registers the repo as part of the\n    // finalization this gate is waiting out.\n    const storagePath = await registeredStoragePath(targetPath);\n    if (storagePath && settled(storagePath)) return;\n    if (Date.now() > deadline) {\n      logger.warn(\n        { targetPath },\n        'analyze finalization not visible after timeout; completing job anyway',\n      );\n      return;\n    }\n    await new Promise((resolve) => setTimeout(resolve, FINALIZE_SETTLE_POLL_MS));\n  }\n};\n\nexport function createLaunchAnalysisWorker(deps: LaunchDeps) {\n  const { jobManager, backend, acquireRepoLock, releaseRepoLock, closeDbHandle } = deps;\n\n  return function launchAnalysisWorker(\n    job: { id: string },\n    targetPath: string,\n    opts: LaunchOptions,\n  ): void {\n    // For waitForSettledIndex: files (re)written by this job have mtimes at or","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/server/analyze-launch.ts#L99-L135","documentation":"After dispatching an analyze job to a worker, the launcher polls the repo's registered storage path (re-resolved each round, because the worker registers the repo during the finalization being waited on) until finalization settles. If FINALIZE_SETTLE_TIMEOUT_MS elapses without the settled state becoming observable, this warning fires and the job is completed anyway rather than blocking forever: the gate trades a possibly stale completion signal for liveness.","triggerScenarios":"A server-launched analyze job whose finalization artifacts (repo registration plus index writes) do not become visible within the settle timeout: saturated or very slow disk, the worker crashing or being OOM-killed mid-finalize, many concurrent analyze jobs contending for I/O, or a network filesystem delaying visibility.","commonSituations":"Very large repositories whose finalization flush exceeds the timeout; containers with slow volumes; NFS/high-latency home dirs for storage; overlapping scheduled analyses starving each other's I/O; worker killed during finalize.","solutions":["After the job reports complete, check index freshness (gitnexus status); if stale, simply re-run analyze","Inspect worker logs for a crash or OOM during finalization and fix that root cause","Reduce concurrent analyze jobs so finalization I/O is not starved","Move the index storage path off a slow network mount onto local disk","If a consistently huge repo keeps tripping it, report it so FINALIZE_SETTLE_TIMEOUT_MS can be raised"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// 'Job completed' is provisional when this warning fired: verify the\n// finalization actually landed before trusting the index.\nconst storagePath = await registeredStoragePath(targetPath);\nconst meta = storagePath ? await loadMeta(storagePath) : undefined;\nif (!meta || !settled(storagePath)) {\n  await relaunchAnalyze(targetPath); // analyze is idempotent — just run it again\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat analyze-job completion as provisional; always verify index freshness afterwards","Keep index storage on local fast disk, not a network mount","Avoid stacking many concurrent analyses on one volume"],"tags":["analyze","worker","timeout","finalization","job-scheduler"],"backgroundTag":"operation-timeout","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}