{"record":{"id":"ae41f72b04b8f5f3","repo":"Graphify-Labs/graphify","slug":"error-refused-to-shrink-graphify-out-graph-json-ae41f7","errorCode":null,"errorMessage":"ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).","messagePattern":"ERROR: refused to shrink graphify-out/graph\\.json \\(existing graph has more nodes; #479\\)\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"tools/skillgen/expected/graphify__skill-copilot.md","lineNumber":437,"sourceCode":"    raise SystemExit(1)\ncommunities = cluster(G)\ncohesion = score_all(G, communities)\ntokens = {'input': extraction.get('input_tokens', 0), 'output': extraction.get('output_tokens', 0)}\ngods = god_nodes(G)\nsurprises = surprising_connections(G, communities)\nlabels = {cid: 'Community ' + str(cid) for cid in communities}\n# Placeholder questions - regenerated with real labels in Step 5\nquestions = suggest_questions(G, communities, labels)\n\n# Export FIRST and honor the #479 shrink-guard: to_json returns False (writing\n# nothing) when the new graph is smaller than the existing graph.json. Only write\n# GRAPH_REPORT.md + the analysis sidecar when the graph was actually written, so\n# they never describe a graph that graph.json doesn't contain (#1392).\nwrote = to_json(G, communities, 'graphify-out/graph.json')\nif not wrote:\n    print('ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).')\n    print('If this shrink is intentional (you deleted files), re-run a full build with --force.')\n    raise SystemExit(1)\nreport = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, 'INPUT_PATH', suggested_questions=questions)\nPath('graphify-out/GRAPH_REPORT.md').write_text(report, encoding=\\\"utf-8\\\")\nanalysis = {\n    'communities': {str(k): v for k, v in communities.items()},\n    'cohesion': {str(k): v for k, v in cohesion.items()},\n    'gods': gods,\n    'surprises': surprises,\n    'questions': questions,\n}\nPath('graphify-out/.graphify_analysis.json').write_text(json.dumps(analysis, indent=2, ensure_ascii=False), encoding=\\\"utf-8\\\")\nprint(f'Graph: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges, {len(communities)} communities')\n\"\n```\n\nIf this step prints `ERROR: Graph is empty`, stop and tell the user what happened - do not proceed to labeling or visualization.\n\nReplace INPUT_PATH with the actual path.\n","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/tools/skillgen/expected/graphify__skill-copilot.md#L419-L455","documentation":"This is a deliberate data-integrity guard (#479) in the graphify build pipeline's export step. graphify.export.to_json() refuses to overwrite an existing graphify-out/graph.json with a smaller graph (fewer nodes), returning False without writing. The wrapper prints this ERROR and exits 1, and — by design — GRAPH_REPORT.md and .graphify_analysis.json are not written either, so no artifact ever describes a graph that graph.json does not contain (#1392).","triggerScenarios":"to_json(G, communities, 'graphify-out/graph.json') returning False because the freshly built G has fewer nodes than the existing graph.json. Happens on re-build after source deletion, a smaller INPUT_PATH than the original build, or an extraction pass that dropped files.","commonSituations":"Incremental or repeated builds after codebase pruning; building from a subdirectory while graph.json came from the repo root; extraction skipping newly-binary or ignored files; stale larger graph.json from a previous branch/checkout.","solutions":["If the shrink is intentional, re-run a full build with --force to overwrite graph.json despite the guard.","Confirm INPUT_PATH is identical to the original build root so relativization covers the same file set.","Diff node counts: compare len(nodes) in graphify-out/.graphify_extract.json-derived G against graph.json to find what dropped.","If graph.json is stale, remove graphify-out/ and rebuild cleanly."],"exampleFix":"# before: refused shrink aborts the pipeline\nwrote = to_json(G, communities, 'graphify-out/graph.json')\nif not wrote:\n    print('ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).')\n    raise SystemExit(1)\n\n# after: intentional shrink -> full rebuild with force\n#   $(cat graphify-out/.graphify_python) build.py --force","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\nexisting = Path('graphify-out/graph.json')\nif existing.exists():\n    old = len(json.loads(existing.read_text(encoding='utf-8')).get('nodes', []))\n    if G.number_of_nodes() < old:\n        print(f'shrink-guard would refuse: {old} -> {G.number_of_nodes()} nodes')\n        raise SystemExit(1)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use one canonical input root for every build of a given graphify-out/.","Force a full rebuild whenever the source tree legitimately shrinks.","Check to_json()'s boolean return and abort the pipeline on False.","Never hand-edit graph.json to inflate node counts to dodge the guard."],"tags":["graphify","data-integrity","shrink-guard","build","export"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}