abhigyanpatwari/GitNexus · warning

Batch enrichment failed, falling back to heuristics:

Error message

Batch enrichment failed, falling back to heuristics:

What it means

Batch enrichment sends up to `batchSize` (default 5) cluster descriptions in one LLM prompt and expects a JSON array back. The whole batch — generate() call plus the regex extract and JSON.parse of the array — sits in one try/catch: any failure logs 'Batch enrichment failed, falling back to heuristics' and every community in that batch drops to its heuristicLabel. Unlike the single-cluster path, a malformed batch response (prose instead of JSON, truncated array, context-window overflow) also triggers this warning because JSON.parse happens inside the try.

Source

Thrown at gitnexus/src/core/ingestion/cluster-enricher.ts:217

      const jsonMatch = response.match(/\[[\s\S]*\]/);
      if (jsonMatch) {
        const parsed = JSON.parse(jsonMatch[0]) as Array<{
          id: string;
          name: string;
          keywords: string[];
          description: string;
        }>;

        for (const item of parsed) {
          enrichments.set(item.id, {
            name: item.name,
            keywords: item.keywords || [],
            description: item.description || '',
          });
        }
      }
    } catch (error) {
      logger.warn({ error }, 'Batch enrichment failed, falling back to heuristics:');
      // Fallback for this batch
      for (const community of batch) {
        enrichments.set(community.id, {
          name: community.heuristicLabel,
          keywords: [],
          description: '',
        });
      }
    }
  }

  // Fill in any missing communities
  for (const community of communities) {
    if (!enrichments.has(community.id)) {
      enrichments.set(community.id, {
        name: community.heuristicLabel,
        keywords: [],
        description: '',

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Inspect the logged { error } field to distinguish API failure (401/429/ETIMEDOUT) from SyntaxError (malformed model output)
  2. For SyntaxError/truncation: lower batchSize (fewer clusters per prompt) so responses fit and stay well-formed
  3. For API errors: fix credentials/endpoint or retry after the rate-limit window
  4. Re-run enrichment — missing entries are backfilled with heuristics automatically

Example fix

// before: one bad item or a truncated array fails the whole batch
const parsed = JSON.parse(jsonMatch[0]) as Item[];
for (const item of parsed) enrichments.set(item.id, item);

// after: validate per item, salvage the good ones
for (const raw of parsed) {
  if (raw && typeof raw.id === 'string' && typeof raw.name === 'string') {
    enrichments.set(raw.id, { name: raw.name, keywords: Array.isArray(raw.keywords) ? raw.keywords : [], description: typeof raw.description === 'string' ? raw.description : '' });
  } // else: this id alone falls back to heuristic, batch survives
}
Defensive patterns

Strategy: retry

Validate before calling

// before each batch: cheap reachability probe; on failure retry once, then shrink the batch
const ok = await llmClient.generate('ping').then(() => true).catch(() => false);
if (!ok) await backoffThenRetry(batch, /* smallerSize */ Math.max(1, batchSize - 2));

Try / catch

try {
  const parsed = JSON.parse(response.match(/\[[\s\S]*\]/)[0]) as Item[];
  for (const raw of parsed) {
    if (raw && typeof raw.id === 'string') enrichments.set(raw.id, normalizeItem(raw)); // per-item guard
  }
} catch (error) {
  for (const community of batch) enrichments.set(community.id, heuristicFor(community)); // batch-level fallback
}

Prevention

When it happens

Trigger: llmClient.generate rejecting (auth/network/rate limit), or the model returning a response whose array extraction fails: JSON.parse throwing on truncated output, the /\[[\s\S]*\]/ greedy match capturing invalid text, or a batch prompt exceeding the model context so the reply is cut off mid-array.

Common situations: Large repos where 5 clusters x 15 members produces prompts near the context limit; models that wrap answers in prose despite the 'Output JSON array' instruction; rate limits and provider outages affecting a whole batch at once.

Related errors


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