{"record":{"id":"07417c545f32fa89","repo":"Graphify-Labs/graphify","slug":"error-refused-to-shrink-graphify-out-graph-json-07417c","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-devin.md","lineNumber":493,"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-out/.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":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/tools/skillgen/expected/graphify__skill-devin.md#L475-L511","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Verify the input root matches the original build so the same file set is relativized.","Compare node counts between the new extraction and graph.json to identify dropped files.","Delete graphify-out/ if it holds stale state, then rebuild."],"exampleFix":"# before: shrink refused, pipeline exits 1\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)\n\n# after: intentional shrink -> clean full rebuild\n#   rm -rf graphify-out/ && <re-run the full /graphify build>","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()).get('nodes', []))\n    if G.number_of_nodes() < old:\n        raise SystemExit(f'refusing shrink {old} -> {G.number_of_nodes()}; full rebuild required')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat a node-count decrease between builds as a signal to rebuild from scratch, not incrementally.","Check to_json()'s return value; False means nothing was persisted.","Only write the report/sidecar after a confirmed successful persist.","Keep the input root stable across builds of the same output directory."],"tags":["graphify","data-integrity","shrink-guard","build","export"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}