{"record":{"id":"e427c44db6374c0e","repo":"Graphify-Labs/graphify","slug":"graph-not-found-source-path","errorCode":null,"errorMessage":"graph not found: {source_path}","messagePattern":"graph not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"graphify/global_graph.py","lineNumber":88,"sourceCode":"    write_json_atomic(_GLOBAL_GRAPH, data, indent=2)\n\n\ndef _file_hash(path: Path) -> str:\n    h = hashlib.sha256()\n    h.update(path.read_bytes())\n    return h.hexdigest()[:16]\n\n\ndef global_add(source_path: Path, repo_tag: str) -> dict:\n    \"\"\"Add or update a project graph in the global graph.\n\n    Returns a summary dict with keys: repo_tag, nodes_added, nodes_removed, skipped.\n    Skipped=True means the source graph hasn't changed since last add.\n    \"\"\"\n    from graphify.build import prefix_graph_for_global, prune_repo_from_graph\n\n    if not source_path.exists():\n        raise FileNotFoundError(f\"graph not found: {source_path}\")\n\n    manifest = _load_manifest()\n    src_hash = _file_hash(source_path)\n\n    existing = manifest[\"repos\"].get(repo_tag, {})\n    existing_path = existing.get(\"source_path\", \"\")\n    if existing_path and existing_path != str(source_path.resolve()):\n        print(\n            f\"[graphify global] warning: repo tag '{repo_tag}' previously pointed to \"\n            f\"{existing_path!r}, now updating to {str(source_path.resolve())!r}. \"\n            f\"Use --as <tag> to give it a different name.\",\n            file=sys.stderr,\n        )\n    if existing.get(\"source_hash\") == src_hash:\n        return {\"repo_tag\": repo_tag, \"nodes_added\": 0, \"nodes_removed\": 0, \"skipped\": True}\n\n    # Load source graph\n    from graphify.security import check_graph_file_size_cap","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/global_graph.py#L70-L106","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\ngraphify global add graph.graphml --as myrepo   # FileNotFoundError: graph not found\n\n# after\ngraphify build .\ngraphify global add graphify-out/graph.graphml --as myrepo","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\nsrc = Path(\"graphify-out/graph.graphml\").resolve()\nif not src.exists():\n    raise SystemExit(f\"build the repo graph first - {src} not found\")\n\nfrom graphify.global_graph import global_add\nglobal_add(src, repo_tag=\"myrepo\")","typeGuard":null,"tryCatchPattern":"try:\n    global_add(src, repo_tag)\nexcept FileNotFoundError as e:\n    if \"graph not found\" in str(e):\n        subprocess.check_call([\"graphify\", \"build\", \".\"])\n        global_add(src, repo_tag)\n    else:\n        raise","preventionTips":["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"],"tags":["file-not-found","global-graph","cli","path"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}