abhigyanpatwari/GitNexus · warning

Analyze worker crashed (code ${code}), retry ${j.retryCount}

Error message

Analyze worker crashed (code ${code}), retry ${j.retryCount}/${MAX_WORKER_RETRIES} in ${delay}ms

What it means

The out-of-process analyze worker (a spawned child doing the actual indexing) exited unexpectedly while its job was still active. The server catches the child's exit, logs the exit code plus the last stderr line the worker printed, and relaunches it with exponential backoff (1s then 2s, at most MAX_WORKER_RETRIES=2 attempts), keeping the job in 'analyzing' with progress phase 'retrying'. The job itself is not failed unless retries are exhausted.

Source

Thrown at gitnexus/src/server/analyze-launch.ts:304

      child.on('error', (err) => {
        releaseRepoLock(analyzeLockKey);
        jobManager.updateJob(job.id, {
          status: 'failed',
          error: `Worker process error: ${err.message}`,
        });
      });

      child.on('exit', (code) => {
        const j = jobManager.getJob(job.id);
        if (!j || isTerminalJobStatus(j.status)) return;

        // Worker crashed — attempt retry if under the limit
        if (j.retryCount < MAX_WORKER_RETRIES) {
          j.retryCount++;
          const delay = 1000 * Math.pow(2, j.retryCount - 1); // 1s, 2s
          const lastErr = stderrChunks.trim().split('\n').pop() || '';
          logger.warn(
            `Analyze worker crashed (code ${code}), retry ${j.retryCount}/${MAX_WORKER_RETRIES} in ${delay}ms` +
              (lastErr ? `: ${lastErr}` : ''),
          );
          jobManager.updateJob(job.id, {
            status: 'analyzing',
            progress: {
              phase: 'retrying',
              percent: j.progress.percent,
              message: `Worker crashed, retrying (${j.retryCount}/${MAX_WORKER_RETRIES})...`,
            },
          });
          stderrChunks = '';
          setTimeout(forkWorker, delay);
        } else {
          // Exhausted retries — permanent failure
          releaseRepoLock(analyzeLockKey);
          jobManager.updateJob(job.id, {
            status: 'failed',

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Read the stderr line appended to the warning — it names the worker's actual crash cause. Address that first (e.g. raise the heap via NODE_OPTIONS=--max-old-space-size=8192, or disable a crash-prone optional grammar with GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1).
  2. If the crash is memory-driven, re-run analyze with more headroom or on a smaller scope/subdirectory.
  3. If something external kills the child (CI timeouts, oom-killer, supervisor), stop it from doing so or run analyze directly instead of via serve.
  4. If both retries exhaust and the job flips to failed, fix the root cause from the stderr line, then re-run `node .gitnexus/run.cjs analyze --index-only`.

Example fix

# before: worker OOMs at default heap, retries twice, then fails
node .gitnexus/run.cjs analyze

# after: give the worker room and skip crash-prone optional grammars
NODE_OPTIONS=--max-old-space-size=8192 GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1 \
  node .gitnexus/run.cjs analyze
Defensive patterns

Strategy: retry

Validate before calling

// Before treating a job as done, confirm a terminal status — a crashed
// worker keeps the job in 'analyzing' with progress.phase 'retrying'.
const job = jobManager.getJob(jobId);
if (job && !isTerminalJobStatus(job.status)) {
  // still running or retrying — keep polling instead of assuming success
}

Prevention

When it happens

Trigger: child.on('exit') fires with a non-zero or null/signal code while jobManager.getJob(job.id) is non-terminal and j.retryCount < 2. Concrete producers: the worker being OOM-killed, a segfault in a native tree-sitter grammar, a missing native module the worker require()s at startup, or an external process (CI, cgroup, supervisor) killing the child mid-run.

Common situations: Indexing very large repos where the worker heap exceeds Node limits; a broken optional tree-sitter grammar build (kotlin/dart/swift) crashing at load; containers with tight memory limits; CI runners that kill long-running child processes.

Related errors


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