abhigyanpatwari/GitNexus · warning · GraphTooLargeError

Graph exceeds the size limit (nodes=${nodes.length}, relatio

Error message

Graph exceeds the size limit (nodes=${nodes.length}, relationships=${relationships.length})

What it means

GraphTooLargeError thrown by parseNdjsonGraphResponse() (via tripBreaker) when the streamed node or relationship count crosses the configured size limit (maxNodes/maxEdges) mid-download. This is the streaming circuit breaker (#2178): a backstop for when pre-fetch stats were missing or stale. It cancels the reader to free the socket, then throws with the counts at the point of tripping. connectToServer catches this and falls into chat-only mode rather than letting a huge graph hang the browser.

Source

Thrown at gitnexus-web/src/services/backend-client.ts:806

      return;
    }
    if (record.type === 'relationship') {
      relationships.push(record.data);
      return;
    }
    if (record.type === 'error') {
      throw new BackendError(record.error, response.status || 500, 'server');
    }
  };

  const tripBreaker = async () => {
    // Free the socket promptly; never let a cancel rejection mask the breaker.
    try {
      await reader.cancel();
    } catch {
      // ignore — we're aborting anyway
    }
    throw new GraphTooLargeError(
      `Graph exceeds the size limit (nodes=${nodes.length}, relationships=${relationships.length})`,
      nodes.length,
      relationships.length,
    );
  };

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    downloaded += value.length;
    onProgress?.(downloaded, total);
    buffer += decoder.decode(value, { stream: true });

    const lines = buffer.split('\n');
    buffer = lines.pop() || '';
    for (const line of lines) {
      parseLine(line);

View on GitHub (pinned to d540b00184)

Solutions

  1. Let the UI fall into chat-only mode (the intended graceful degradation) — the agent still works without the graph
  2. If you need the graph, reduce the repo scope (analyze a subdirectory or exclude vendor/node_modules)
  3. Raise the thresholds (LARGE_GRAPH_NODE_THRESHOLD / LARGE_GRAPH_EDGE_THRESHOLD) if your browser can handle it — but beware memory pressure
  4. Re-analyze with a tighter include/exclude config to shrink the graph

Example fix

// before — caller treats graph-too-large as a fatal error
try { await loadGraph(repo); }
catch (e) { showError('Failed to load graph'); }

// after — degrade to chat-only mode on GraphTooLargeError
try { await loadGraph(repo); }
catch (e) {
  if (e instanceof GraphTooLargeError) {
    enterChatOnlyMode(); // agent still usable, graph view disabled
  } else throw e;
}
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-fetch: use stats to decide whether to attempt the graph load
import { decideSkipGraph } from '../lib/graph-load-decision.js';
const skip = decideSkipGraph(repo.stats); // returns true if thresholds exceeded
if (skip) {
  enterChatOnlyMode(); // skip the streaming fetch entirely
} else {
  await loadGraph(repo); // may still trip the streaming breaker
}

Type guard

import { GraphTooLargeError } from './services/backend-client.js';
function isGraphTooLarge(e: unknown): e is GraphTooLargeError {
  return e instanceof GraphTooLargeError;
}

Try / catch

try {
  return await parseNdjsonGraphResponse(response, onProgress, maxNodes, maxEdges);
} catch (e) {
  if (e instanceof GraphTooLargeError) {
    // e.nodeCount / e.relationshipCount are the counts at trip time
    enterChatOnlyMode(); // graceful degradation — agent still works
    return { nodes: [], relationships: [] };
  }
  throw e;
}

Prevention

When it happens

Trigger: During NDJSON streaming, after pushing a node or relationship, overLimit() returns true (nodes.length > maxNodes OR relationships.length > maxEdges). tripBreaker() runs: reader.cancel(), then throw GraphTooLargeError with current counts. Defaults come from LARGE_GRAPH_NODE_THRESHOLD / LARGE_GRAPH_EDGE_THRESHOLD in ui-constants.

Common situations: Loading a genuinely large repository (monorepo, huge dependency graph) where the pre-fetch stats undercounted or were absent; a repo whose edge count balloons due to dense call graphs; the streaming backstop firing because decideSkipGraph didn't have accurate stats.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/645248d8b5f1c47d. Report an issue: GitHub.