{"record":{"id":"c09954a22e6a9d3b","repo":"Graphify-Labs/graphify","slug":"graph-file-not-found-resolved","errorCode":null,"errorMessage":"Graph file not found: {resolved}","messagePattern":"Graph file not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"graphify/security.py","lineNumber":352,"sourceCode":"\n    base = base.resolve()\n    if not base.exists():\n        raise ValueError(\n            f\"Graph base directory does not exist: {base}. \"\n            \"Run /graphify first to build the graph.\"\n        )\n\n    resolved = Path(path).resolve()\n    try:\n        resolved.relative_to(base)\n    except ValueError:\n        raise ValueError(\n            f\"Path {path!r} escapes the allowed directory {base}. \"\n            \"Only paths inside graphify-out/ are permitted.\"\n        )\n\n    if not resolved.exists():\n        raise FileNotFoundError(f\"Graph file not found: {resolved}\")\n\n    return resolved\n\n\ndef check_graph_file_size_cap(path: Path) -> None:\n    \"\"\"Reject *path* if its size exceeds the configured graph-file cap.\n\n    Protects callers from memory bombs by failing fast before a multi-GiB\n    graph.json is read into memory and JSON-parsed. Silently returns when\n    ``path.stat()`` cannot be read — the caller's own existence/path check\n    is expected to surface a clearer error in that case.\n\n    The cap is resolved on every call via :func:`_max_graph_file_bytes`, so the\n    ``GRAPHIFY_MAX_GRAPH_BYTES`` env var can be set before import and still\n    apply.\n\n    Raises:\n        ValueError - file size exceeds the cap. The message includes the","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/security.py#L334-L370","documentation":"Raised by the graph-path validator in graphify/security.py when a path passed the base-directory and containment checks but the resolved file does not exist on disk. It is the plain missing-file case within the otherwise-restricted graphify-out/ directory.","triggerScenarios":"Requesting a specific artifact (e.g. graphify-out/wiki/index.md or graph.json) that has not been generated yet, requesting it after the output was cleaned, or a stale path cached from a previous build with different content.","commonSituations":"Querying wiki files before the wiki-generation step ran; graph output deleted by a clean/build step between runs; file name changed between graphify versions; concurrent rebuild moved/rewrote files while a query was in flight.","solutions":["Rebuild the graph (/graphify) so all expected artifacts are regenerated.","List what actually exists under graphify-out/ and adjust the requested filename.","If a rebuild is running concurrently, retry the read after it completes.","Check for cleaned outputs (git clean, CI caching) and restore or regenerate them."],"exampleFix":"# before\np = resolve_graph_path(\"graphify-out/graph.json\")  # FileNotFoundError\n\n# after: verify what exists before requesting\nbase = Path(\"graphify-out\")\nif not (base / \"graph.json\").exists():\n    rebuild_graph()\np = resolve_graph_path(\"graphify-out/graph.json\")","handlingStrategy":"validation","validationCode":"def graph_file_ready(base: Path, rel: str = \"graph.json\") -> bool:\n    return (base / rel).is_file()","typeGuard":"def graph_file_exists(path: str | Path) -> bool:\n    p = Path(path).resolve()\n    return p.suffix == \".json\" and p.exists()","tryCatchPattern":"try:\n    p = resolve_graph_path(path)\nexcept FileNotFoundError as e:\n    if \"Graph file not found\" in str(e):\n        rebuild_graph()  # or prompt the user to run /graphify\n        p = resolve_graph_path(path)\n    else:\n        raise","preventionTips":["Check Path(...).exists() right before requesting graph artifacts.","Regenerate the graph after clean steps that wipe graphify-out/.","Cache artifact paths per build, not across builds."],"tags":["filesystem","graph","missing-file"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}