abhigyanpatwari/GitNexus · warning

Worker ${workerIndex} parse job idle timeout. Splitting into

Error message

Worker ${workerIndex} parse job idle timeout. Splitting into ${first.items.length}/${second.items.length} item jobs.

What it means

On an idle timeout for a multi-item job, the pool bisects the job at its midpoint into two smaller jobs (inheriting attempt count, bumping splitDepth, each with recomputed byte estimates and the next backoff timeout) and requeues them at the front. The warn records the original timeout/size plus both halves' item counts so operators can watch the bisection converge on the pathological item.

Source

Thrown at gitnexus/src/core/ingestion/workers/worker-pool.ts:1900

            items: firstItems,
            estimatedBytes: firstItems.reduce((sum, item) => sum + estimateItemBytes(item), 0),
            attempt: job.attempt,
            splitDepth: job.splitDepth + 1,
            chunkHash: job.chunkHash,
            timeoutMs: nextTimeout,
            cumulativeTimeoutMs: nextCumulative,
          };
          const second: WorkerJob<TInput> = {
            startIndex: job.startIndex + midpoint,
            items: secondItems,
            estimatedBytes: secondItems.reduce((sum, item) => sum + estimateItemBytes(item), 0),
            attempt: job.attempt,
            splitDepth: job.splitDepth + 1,
            chunkHash: job.chunkHash,
            timeoutMs: nextTimeout,
            cumulativeTimeoutMs: nextCumulative,
          };
          logger.warn(
            {
              workerIndex,
              timeoutSec: job.timeoutMs / 1000,
              items: job.items.length,
              estimatedBytes: job.estimatedBytes,
              lastProgress,
              firstSplitItems: first.items.length,
              secondSplitItems: second.items.length,
              nextTimeoutSec: nextTimeout / 1000,
            },
            `Worker ${workerIndex} parse job idle timeout. Splitting into ${first.items.length}/${second.items.length} item jobs.`,
          );
          // Preserve intuitive retry order; final result order is still enforced by startIndex sort.
          jobs.unshift(first, second);
          return { kind: 'retry' };
        }

        const nextAttempt = job.attempt + 1;

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Let the split converge — each bisection isolates the slow item; watch the warn's first/secondSplitItems counts narrow toward 1
  2. Reduce GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES (or subBatchSize) so big files land in smaller jobs from the start
  3. Raise GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS if your hardware makes the initial budget unrealistic
  4. If splitting always isolates the same file, exclude or shrink that file — the single-item retry/quarantine path is next for it

Example fix

# before
export GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=   # big files batched together → split warns
# after
export GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=1048576   # 1MB sub-batches, fewer splits
Defensive patterns

Strategy: retry

Validate before calling

// Prevent avoidable splits by sizing sub-batches to your file mix:
if (!process.env.GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES) {
  process.env.GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES = String(1024 * 1024); // 1MB
}

Prevention

When it happens

Trigger: A sub-batch with multiple items going idle-silent past its timeout: the job splits into first/second WorkerJob halves and jobs.unshift(first, second) requeues them; final result order stays correct via the startIndex sort.

Common situations: One heavy file inside a mixed sub-batch stalling the whole batch; timeouts calibrated for typical files on machines slower than expected; large values of subBatchMaxBytes packing many big files into one job.

Understand the failure class

Related errors


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