Graphify-Labs/graphify · error · SystemExit

ERROR: refused to shrink graphify-out/graph.json (fewer node

Error message

ERROR: refused to shrink graphify-out/graph.json (fewer nodes than the existing graph). Run a full rebuild to be safe.

What it means

The #479 shrink-guard in the graphify build pipeline's persist step. to_json(G, communities, 'graphify-out/graph.json') returns False — writing nothing — when the new graph has fewer nodes than the existing graph.json. This devin-variant wrapper prints this ERROR and exits 1 before generate()/write_text() run, so the report and analysis sidecar never describe a graph that was not persisted (#1392).

Source

Thrown at tools/skillgen/expected/graphify__skill-devin.md:493

    print('ERROR: Graph is empty - extraction produced no nodes.')
    print('Possible causes: all files were skipped, binary-only corpus, or extraction failed.')
    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)

# Persist the graph first and only write the report/analysis if it actually
# persisted - to_json refuses to shrink an existing graph.json (#479), and a
# report describing a graph we did not write would be a lie (#1392).
wrote = to_json(G, communities, 'graphify-out/graph.json')
if not wrote:
    print('ERROR: refused to shrink graphify-out/graph.json (fewer nodes than the existing graph). Run a full rebuild to be safe.')
    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)

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))
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

  1. Run a full rebuild (the message's own remedy) — from a clean state or with the force flag — so the smaller graph legitimately replaces the old one.
  2. Verify the input root matches the original build so the same file set is relativized.
  3. Compare node counts between the new extraction and graph.json to identify dropped files.
  4. Delete graphify-out/ if it holds stale state, then rebuild.

Example fix

# before: shrink refused, pipeline exits 1
wrote = to_json(G, communities, 'graphify-out/graph.json')
if not wrote:
    print('ERROR: refused to shrink graphify-out/graph.json (fewer nodes than the existing graph). Run a full rebuild to be safe.')
    raise SystemExit(1)

# after: intentional shrink -> clean full rebuild
#   rm -rf graphify-out/ && <re-run the full /graphify build>
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

existing = Path('graphify-out/graph.json')
if existing.exists():
    old = len(json.loads(existing.read_text()).get('nodes', []))
    if G.number_of_nodes() < old:
        raise SystemExit(f'refusing shrink {old} -> {G.number_of_nodes()}; full rebuild required')

Prevention

When it happens

Trigger: Calling to_json() with a graph smaller than the on-disk graph.json: rebuild after file deletion, smaller input root than the original build, or an extraction pass that silently dropped files.

Common situations: Rebuilding after cleaning/pruning a repo; running the build against a subtree while graph.json was built from the full root; partial re-extraction; stale graph.json from a larger prior checkout.

Related errors


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/07417c545f32fa89. Report an issue: GitHub.