{"record":{"id":"96b022875444920f","repo":"Graphify-Labs/graphify","slug":"cannot-stat-p-exc","errorCode":null,"errorMessage":"cannot stat {p}: {exc}","messagePattern":"cannot stat (.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"graphify/cli.py","lineNumber":2244,"sourceCode":"        # Usage: graphify merge-driver %O %A %B  (set in .git/config merge driver)\n        if len(sys.argv) < 5:\n            print(\"Usage: graphify merge-driver <base> <current> <other>\", file=sys.stderr)\n            sys.exit(1)\n        _base_path, _current_path, _other_path = sys.argv[2], sys.argv[3], sys.argv[4]\n        # Hard caps so a malicious or corrupted graph.json cannot exhaust memory\n        # at parse time. 50 MB / 100k nodes are well above any realistic graph\n        # (typical graphs are <5 MB / <50k nodes); anything larger should fail\n        # the merge so a human can investigate.\n        _MERGE_MAX_BYTES = 50 * 1024 * 1024\n        _MERGE_MAX_NODES = 100_000\n        import networkx as _nx\n        from networkx.readwrite import json_graph as _jg\n        def _load_graph(p: str):\n            path_obj = Path(p)\n            try:\n                size = path_obj.stat().st_size\n            except OSError as exc:\n                raise RuntimeError(f\"cannot stat {p}: {exc}\") from exc\n            if size > _MERGE_MAX_BYTES:\n                raise RuntimeError(\n                    f\"graph.json {p} is {size} bytes, exceeds {_MERGE_MAX_BYTES}-byte cap\"\n                )\n            data = json.loads(path_obj.read_text(encoding=\"utf-8\"))\n            # A committed raw (--no-cluster) graph stores edges under \"edges\";\n            # parse via the shared links/edges-normalizing loader (#2212).\n            from graphify.paths import load_node_link_graph as _lnlg\n            return _lnlg(data), data\n        try:\n            G_cur, _ = _load_graph(_current_path)\n            G_oth, _ = _load_graph(_other_path)\n        except Exception as exc:\n            print(f\"[graphify merge-driver] error loading graphs: {exc}\", file=sys.stderr)\n            sys.exit(1)  # surface the conflict so git doesn't accept a corrupt merge\n        merged = _nx.compose(G_cur, G_oth)\n        if merged.number_of_nodes() > _MERGE_MAX_NODES:\n            print(","sourceCodeStart":2226,"sourceCodeEnd":2262,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/cli.py#L2226-L2262","documentation":"Shrink-guard in the devin fragment's export step (tools/skillgen/fragments/core/devin.md:493). to_json(G, communities, 'graphify-out/graph.json') refuses to overwrite an existing graph.json that has more nodes, returns False, and the script exits 1 with the older 'Run a full rebuild to be safe' wording (no --force flag mentioned). GRAPH_REPORT.md and the analysis sidecar are only written after a successful persist (#1392).","triggerScenarios":"A rebuild/update yielded fewer nodes than the existing graphify-out/graph.json: files deleted from the corpus, files skipped in re-extraction, or a stale larger graph.json from a previous run on a bigger tree.","commonSituations":"graphify update after pruning or branch switch; partial extraction due to parse failures; leftover graph.json from a different repository; running the pipeline twice against different paths.","solutions":["Do a full rebuild as instructed — with the modern CLI, a full build with --force — so graph.json reflects the current corpus.","If the shrink is unexpected, compare existing vs new node counts and inspect extract/detect sidecars for skipped files.","Remove stale graphify-out/graph.json before rebuilding when the output dir is inherited.","Keep INPUT_PATH stable between full builds and incremental updates to keep node sets comparable."],"exampleFix":"# before\n/graphify update .\n# ERROR: refused to shrink ... fewer nodes ...\n\n# after\n/graphify build --force .","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\nold_n = len(json.loads(Path('graphify-out/graph.json').read_text(encoding='utf-8')).get('nodes', []))\nnew_n = len(json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding='utf-8')).get('nodes') or [])\nif new_n < old_n:\n    print(f'shrink {old_n}->{new_n}: full rebuild (--force) required before export')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pre-check node-count deltas and require a full rebuild on shrink.","Use --force after intentional file deletions.","Do not carry graphify-out/ across projects.","Audit skip lists when the node count regresses unexpectedly."],"tags":["graphify","devin","shrink-guard","export","data-integrity"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}