{"record":{"id":"8283ead8d36badec","repo":"Graphify-Labs/graphify","slug":"error-refused-to-shrink-graphify-out-graph-json-8283ea","errorCode":null,"errorMessage":"ERROR: refused to shrink graphify-out/graph.json (fewer nodes than the existing graph). Run a full rebuild to be safe.","messagePattern":"ERROR: refused to shrink graphify-out/graph\\.json \\(fewer nodes than the existing graph\\)\\. Run a full rebuild to be safe\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"tools/skillgen/expected/graphify__skill-aider.md","lineNumber":428,"sourceCode":"    print('ERROR: Graph is empty - extraction produced no nodes.')\n    print('Possible causes: all files were skipped, binary-only corpus, or extraction failed.')\n    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# Persist the graph first and only write the report/analysis if it actually\n# persisted - to_json refuses to shrink an existing graph.json (#479), and a\n# report describing a graph we did not write would be a lie (#1392).\nwrote = to_json(G, communities, 'graphify-out/graph.json')\nif not wrote:\n    print('ERROR: refused to shrink graphify-out/graph.json (fewer nodes than the existing graph). Run a full rebuild to be safe.')\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)\n\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_analysis.json').write_text(json.dumps(analysis, indent=2))\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.","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/tools/skillgen/expected/graphify__skill-aider.md#L410-L446","documentation":"The shrink-guard error in the generated aider render of the graphify skill: to_json() returns False instead of writing when the new graph has fewer nodes than the existing graph.json (#479), and the Step 4 block exits with this message before writing GRAPH_REPORT.md or .graphify_analysis.json (#1392 — a report must never describe a graph that was not persisted). The expected-render wording differs slightly ('fewer nodes than the existing graph. Run a full rebuild to be safe.') and predates the --force hint.","triggerScenarios":"Running the aider skill's Step 4 build when the freshly built graph has fewer nodes than graphify-out/graph.json — deleted/renamed sources, expanded .graphifyignore, partially failed extraction, or building a smaller subpath over an existing graphify-out/.","commonSituations":"Post-cleanup incremental builds; switching input paths without clearing graphify-out/; extraction where some files errored; dedup collapsing node count.","solutions":["If the shrink is intended, do a full rebuild: delete graphify-out/graph.json (or the whole graphify-out/) and re-run the build block","If unintended, diff the node sources: check .graphify_extract.json for files that failed to extract and re-run extraction","Review .graphifyignore changes that may have excluded previously indexed files"],"exampleFix":"# before\nwrote = to_json(G, communities, 'graphify-out/graph.json')\n# → ERROR: refused to shrink (fewer nodes than existing graph)\n\n# after (intentional shrink)\nPath('graphify-out/graph.json').unlink()   # or full rebuild with --force in the current skill\nwrote = to_json(G, communities, 'graphify-out/graph.json')","handlingStrategy":"fallback","validationCode":"from pathlib import Path\nimport json\n\ngraph_path = Path('graphify-out/graph.json')\nexisting = len(json.loads(graph_path.read_text())['nodes']) if graph_path.exists() else -1\nif existing >= 0 and G.number_of_nodes() < existing:\n    if SHRINK_INTENTIONAL:\n        graph_path.unlink()  # allow the smaller graph to be written\n    else:\n        raise SystemExit('node count dropped — investigate extraction before writing')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run a full rebuild (delete graphify-out/) whenever the source tree shrank on purpose","Compare node counts before to_json() so shrink decisions are explicit, not discovered via the error","Never mix graph.json from one run with sidecars from another — rebuild produces all three atomically"],"tags":["graphify","generated-skill","shrink-guard","data-integrity","aider"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}