Graphify-Labs/graphify · error · FileNotFoundError
graph not found: {source_path}
Error message
graph not found: {source_path} What it means
Raised by global_add when the per-repo graph file it was told to register in the global (multi-repo) graph does not exist on disk. The global graph workflow reads a previously built graphify output (e.g. graphify-out/graph.graphml) and merges it under a repo tag, so a missing source file is a hard FileNotFoundError before any manifest state is touched.
Source
Thrown at graphify/global_graph.py:88
write_json_atomic(_GLOBAL_GRAPH, data, indent=2)
def _file_hash(path: Path) -> str:
h = hashlib.sha256()
h.update(path.read_bytes())
return h.hexdigest()[:16]
def global_add(source_path: Path, repo_tag: str) -> dict:
"""Add or update a project graph in the global graph.
Returns a summary dict with keys: repo_tag, nodes_added, nodes_removed, skipped.
Skipped=True means the source graph hasn't changed since last add.
"""
from graphify.build import prefix_graph_for_global, prune_repo_from_graph
if not source_path.exists():
raise FileNotFoundError(f"graph not found: {source_path}")
manifest = _load_manifest()
src_hash = _file_hash(source_path)
existing = manifest["repos"].get(repo_tag, {})
existing_path = existing.get("source_path", "")
if existing_path and existing_path != str(source_path.resolve()):
print(
f"[graphify global] warning: repo tag '{repo_tag}' previously pointed to "
f"{existing_path!r}, now updating to {str(source_path.resolve())!r}. "
f"Use --as <tag> to give it a different name.",
file=sys.stderr,
)
if existing.get("source_hash") == src_hash:
return {"repo_tag": repo_tag, "nodes_added": 0, "nodes_removed": 0, "skipped": True}
# Load source graph
from graphify.security import check_graph_file_size_capView on GitHub (pinned to 7fe58b0b0f)
Solutions
- Build the repo graph first: `graphify build .` in that repo, then re-run the global add pointing at the generated file
- Check the path: `ls graphify-out/` and pass the actual graph file (commonly graphify-out/graph.graphml)
- Use an absolute path to avoid cwd-dependent resolution
Example fix
# before graphify global add graph.graphml --as myrepo # FileNotFoundError: graph not found # after graphify build . graphify global add graphify-out/graph.graphml --as myrepo
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
src = Path("graphify-out/graph.graphml").resolve()
if not src.exists():
raise SystemExit(f"build the repo graph first - {src} not found")
from graphify.global_graph import global_add
global_add(src, repo_tag="myrepo") Try / catch
try:
global_add(src, repo_tag)
except FileNotFoundError as e:
if "graph not found" in str(e):
subprocess.check_call(["graphify", "build", "."])
global_add(src, repo_tag)
else:
raise Prevention
- Chain build before add in scripts: `graphify build . && graphify global add graphify-out/graph.graphml`
- Always pass an absolute, resolved path to global_add
- Assert the output file exists right after build before referencing it
When it happens
Trigger: Calling global_add(source_path, repo_tag) — e.g. `graphify global add graphify-out/graph.graphml` — where source_path.exists() is False: wrong path, graph not built yet, or running from a directory where the relative path doesn't resolve.
Common situations: Running `graphify global add` before `graphify build` in a fresh clone; passing the repo root instead of the .graphml output; path typos or shell quoting; running the command from a different cwd with a relative path.
Related errors
- repo '{repo_tag}' not in global graph
- Claude Code CLI not found on $PATH
- gws is required for Google Workspace export. Install it from
- No git repository found at or above {path.resolve()}
- graphify install is incomplete: missing always-on block '{ba
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/e427c44db6374c0e.
Report an issue: GitHub.