Graphify-Labs/graphify · error · SystemExit
ERROR: refused to shrink graphify-out/graph.json (existing g
Error message
ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).
What it means
This is a deliberate data-integrity guard (#479) in the graphify build pipeline's Step-4 export snippet, not a library exception. graphify.export.to_json() compares the freshly built graph against the existing graphify-out/graph.json and returns False (writing nothing) when the new graph has fewer nodes. The wrapper script prints this ERROR and raises SystemExit(1) so that GRAPH_REPORT.md and .graphify_analysis.json are never written for a graph that graph.json does not actually contain (#1392).
Source
Thrown at tools/skillgen/expected/graphify__skill-codex.md:434
raise SystemExit(1)
communities = cluster(G)
cohesion = score_all(G, communities)
tokens = {'input': extraction.get('input_tokens', 0), 'output': extraction.get('output_tokens', 0)}
gods = god_nodes(G)
surprises = surprising_connections(G, communities)
labels = {cid: 'Community ' + str(cid) for cid in communities}
# Placeholder questions - regenerated with real labels in Step 5
questions = suggest_questions(G, communities, labels)
# Export FIRST and honor the #479 shrink-guard: to_json returns False (writing
# nothing) when the new graph is smaller than the existing graph.json. Only write
# GRAPH_REPORT.md + the analysis sidecar when the graph was actually written, so
# they never describe a graph that graph.json doesn't contain (#1392).
wrote = to_json(G, communities, 'graphify-out/graph.json')
if not wrote:
print('ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).')
print('If this shrink is intentional (you deleted files), re-run a full build with --force.')
raise SystemExit(1)
report = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, 'INPUT_PATH', suggested_questions=questions)
Path('graphify-out/GRAPH_REPORT.md').write_text(report, encoding=\"utf-8\")
analysis = {
'communities': {str(k): v for k, v in communities.items()},
'cohesion': {str(k): v for k, v in cohesion.items()},
'gods': gods,
'surprises': surprises,
'questions': questions,
}
Path('graphify-out/.graphify_analysis.json').write_text(json.dumps(analysis, indent=2, ensure_ascii=False), encoding=\"utf-8\")
print(f'Graph: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges, {len(communities)} communities')
"
```
If this step prints `ERROR: Graph is empty`, stop and tell the user what happened - do not proceed to labeling or visualization.
Replace INPUT_PATH with the actual path.
View on GitHub (pinned to 7fe58b0b0f)
Solutions
- If the shrink is intentional (you deleted source files), re-run the full build with --force so the shrink-guard is bypassed and graph.json is overwritten.
- Verify INPUT_PATH matches the exact same root used for the original build — a smaller root relativizes fewer source files and yields fewer nodes.
- Inspect graphify-out/.graphify_extract.json and compare its node count against graph.json to see which files dropped out (skipped, binary-only, or extraction failure).
- If graph.json is stale garbage from an abandoned run, delete graphify-out/ entirely and rebuild from scratch.
Example fix
# before: re-running build after deleting files, guard refuses
wrote = to_json(G, communities, 'graphify-out/graph.json')
if not wrote:
print('ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).')
raise SystemExit(1)
# after: intentional shrink -> force a full rebuild
# bash: re-run the build with the force flag
# $(cat graphify-out/.graphify_python) build_step.py --force Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
new_count = G.number_of_nodes()
existing = Path('graphify-out/graph.json')
if existing.exists():
old_count = len(json.loads(existing.read_text(encoding='utf-8')).get('nodes', []))
if new_count < old_count:
print(f'Would shrink graph.json: {old_count} -> {new_count} nodes. Aborting before to_json.')
raise SystemExit(1) Prevention
- Always build from the same INPUT_PATH root so repeated builds cover the identical file set.
- After deleting source files, immediately run a full rebuild with --force instead of an incremental one.
- Treat to_json() returning False as a hard stop — never write the report or sidecar afterward.
- Keep graphify-out/ out of version control so stale, larger graph.json files never leak between branches.
When it happens
Trigger: Calling to_json(G, communities, 'graphify-out/graph.json') after build_from_json() produced fewer nodes than the existing graph.json — typically because source files were deleted, INPUT_PATH pointed at a smaller subtree than the original build, or extraction skipped/dropped files. Only fires when graphify-out/graph.json already exists and is larger.
Common situations: Re-running a full build after pruning a codebase; running the build step against a subdirectory while graph.json was built from the repo root; a partial re-extract (some files skipped as binary or by ignore rules) silently shrinking the node set; stale graph.json left over from a previous larger checkout.
Related errors
- ERROR: refused to shrink graphify-out/graph.json (existing g
- ERROR: refused to shrink graphify-out/graph.json (fewer node
- ERROR: refused to shrink graphify-out/graph.json (existing g
- ERROR: refused to shrink graphify-out/graph.json (existing g
- ERROR: refused to shrink graphify-out/graph.json (existing g
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/0b072410c5505482.
Report an issue: GitHub.