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
- Let the UI fall into chat-only mode (the intended graceful degradation) — the agent still works without the graph
- If you need the graph, reduce the repo scope (analyze a subdirectory or exclude vendor/node_modules)
- Raise the thresholds (LARGE_GRAPH_NODE_THRESHOLD / LARGE_GRAPH_EDGE_THRESHOLD) if your browser can handle it — but beware memory pressure
- 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
- Use pre-fetch stats (decideSkipGraph) to skip obviously large repos before streaming
- For huge repos, analyze a subdirectory or exclude vendor/node_modules to shrink the graph
- Raise LARGE_GRAPH_NODE_THRESHOLD / LARGE_GRAPH_EDGE_THRESHOLD only if you've tested browser memory headroom
- Always handle GraphTooLargeError with a chat-only fallback — it's the designed degradation path, not a crash
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
- server
- {label} exceeds the bounded evidence limit
- candidate overlay exceeds the {MAX_CANDIDATE_ENTRIES}-entry
- candidate overlay path exceeds {MAX_CANDIDATE_PATH_BYTES} by
- candidate overlay exceeds the {MAX_CANDIDATE_FILES}-file lim
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/645248d8b5f1c47d.
Report an issue: GitHub.