Graphify-Labs/graphify · error · RuntimeError
Cannot read graph file {path}: {exc}. Re-run 'graphify extra
Error message
Cannot read graph file {path}: {exc}. Re-run 'graphify extract' to regenerate it. What it means
The #479 shrink-guard in the Windows variant of the export step (tools/skillgen/expected/graphify__skill-windows.md:459). to_json() refuses to overwrite an existing graphify-out/graph.json that has more nodes than the newly built graph, returns False, and the script exits 1 with the '--force' hint. The report and analysis sidecar are only written after a successful graph write, keeping all artifacts consistent (#1392).
Source
Thrown at graphify/affected.py:293
# The relation SITE in this node's file (call/import/reference line),
# labeled by [via_relation] so it's never mistaken for a def line.
location = f"{hit.via_file or data.get('source_file') or '-'}:{hit.via_location}"
else:
location = _format_location(data) # honest fallback: the node's own def line
lines.append(
f"- {_node_label(graph, hit.node_id)} [{hit.via_relation}] {location}"
)
return "\n".join(lines)
def load_graph(path: Path) -> nx.Graph:
import json
from networkx.readwrite import json_graph
try:
raw = json.loads(path.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError) as exc:
raise RuntimeError(
f"Cannot read graph file {path}: {exc}. "
"Re-run 'graphify extract' to regenerate it."
) from exc
# Force directed so stored caller→callee direction survives the round-trip;
# mirrors serve.py and __main__.py (#1174).
raw = {**raw, "directed": True}
# Normalize the edge key: graphify's `extract` output uses "edges" while
# networkx's node_link_data default is "links". Without this, an edges-keyed
# graph.json raises an uncaught KeyError: 'links' here — every other loader
# (__main__.py) already normalizes this (#738; same class as #1198).
if "links" not in raw and "edges" in raw:
raw = dict(raw, links=raw["edges"])
try:
return json_graph.node_link_graph(raw, edges="links")
except TypeError:
return json_graph.node_link_graph(raw)
View on GitHub (pinned to 7fe58b0b0f)
Solutions
- If the corpus legitimately shrank, re-run a full build with --force so the smaller graph intentionally replaces graph.json.
- Otherwise diagnose the node-count regression: compare len(nodes) in the existing graph.json with the new G.number_of_nodes(); check .graphify_detect.json for skipped files.
- Verify the INPUT_PATH used by the PowerShell run matches the original full-build path.
- If graphify-out is inherited/stale, delete it and rebuild from scratch.
Example fix
# before & (Get-Content graphify-out\.graphify_python) graphify update . # ERROR: refused to shrink ... (#479) # after & (Get-Content graphify-out\.graphify_python) graphify build --force .
Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
old = json.loads(Path('graphify-out/graph.json').read_text(encoding='utf-8')).get('nodes', [])
new = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding='utf-8')).get('nodes') or []
if len(new) < len(old):
print(f'shrink detected {len(old)} -> {len(new)}: use --force full rebuild if intentional') Prevention
- Treat any drop in node count as a signal to audit skipped files before exporting.
- Use --force full rebuild after intentional corpus deletions.
- Keep one graphify-out/ per repository and per INPUT_PATH base.
- Record the node count of the last successful build and compare on every update.
When it happens
Trigger: The PowerShell pipeline rebuilt a graph with fewer nodes than what is stored in the existing graphify-out/graph.json — e.g. an incremental update after files were deleted, a partial extraction that skipped files, or an old graph.json from a larger corpus still sitting in graphify-out/.
Common situations: graphify update after pruning the codebase; stale output directory from a previous project or branch with more files; PowerShell path handling causing a subset of files to be scanned; switching the target path without clearing graphify-out/.
Related errors
- module {__name__!r} has no attribute {name!r}
- cannot stat {p}: {exc}
- ERROR: refused to shrink graphify-out/graph.json (existing g
- ERROR: refused to shrink graphify-out/graph.json (existing g
- ERROR: refused to shrink graphify-out/graph.json (fewer node
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/54536efd97e6cd8d.
Report an issue: GitHub.