{"record":{"id":"e6bfc56ddc843ab9","repo":"Graphify-Labs/graphify","slug":"graph-path-must-be-a-json-file-got-graph-path","errorCode":null,"errorMessage":"Graph path must be a .json file, got: {graph_path!r}","messagePattern":"Graph path must be a \\.json file, got: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"graphify/serve.py","lineNumber":29,"sourceCode":"import threading\nfrom typing import NamedTuple\nimport networkx as nx\nfrom networkx.readwrite import json_graph\nfrom graphify.security import sanitize_label, check_graph_file_size_cap\nfrom graphify.build import edge_data, edge_datas\nfrom graphify.paths import default_graph_json as _default_graph_json\n\ntry:\n    import jieba as _jieba  # type: ignore[import-untyped]\nexcept ImportError:\n    _jieba = None\n\n\ndef _load_graph(graph_path: str) -> nx.Graph:\n    try:\n        resolved = Path(graph_path).resolve()\n        if resolved.suffix != \".json\":\n            raise ValueError(f\"Graph path must be a .json file, got: {graph_path!r}\")\n        if not resolved.exists():\n            raise FileNotFoundError(f\"Graph file not found: {resolved}\")\n        check_graph_file_size_cap(resolved)\n        safe = resolved\n        data = json.loads(safe.read_text(encoding=\"utf-8\"))\n        if \"links\" not in data and \"edges\" in data:\n            data = dict(data, links=data[\"edges\"])\n        # Stash the on-disk logical flag before the load-time override below:\n        # `directed: True` exists only so renderers can recover stored arc\n        # order (#2309); tools that care about logical direction (#2487) must\n        # not mistake the override for graph truth.\n        _logical_directed = bool(data.get(\"directed\", False))\n        data = {**data, \"directed\": True}\n        try:\n            from graphify.build import graph_has_legacy_ids as _legacy\n            if _legacy(data.get(\"nodes\", [])):\n                print(\n                    \"[graphify] note: this graph uses the pre-#1504 node-ID scheme; \"","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/serve.py#L11-L47","documentation":"Raised in _load_graph (graphify/serve.py) when the graph path, after Path.resolve(), does not end in the .json suffix. The loader only accepts node-link JSON files, and the check runs before existence and size checks so mis-typed inputs fail fast with a clear reason.","triggerScenarios":"Calling _load_graph / graphify serve with a path like graphify-out/graph.jsonl, graph.txt, a directory, or a path with no extension; also paths whose final component after resolve() is not the JSON file itself.","commonSituations":"Passing a GraphML/GML/JSONL export by mistake; passing the graphify-out directory instead of the graph.json inside it; typos or shell-glob expansion producing a non-.json path; tab-completion picking the wrong file.","solutions":["Point the loader at the actual node-link JSON: graphify-out/graph.json.","If your graph is in another format, convert it to node-link JSON (nx.node_link_data) first.","Quote the path and check for shell glob expansion when passing it on the command line.","Verify the resolved path programmatically: Path(p).resolve().suffix should be '.json' before calling."],"exampleFix":"# before\nG = _load_graph(\"graphify-out\")            # directory\nG = _load_graph(\"data/graph.graphml\")       # wrong format\n\n# after\nG = _load_graph(\"graphify-out/graph.json\")","handlingStrategy":"type-guard","validationCode":"from pathlib import Path\n\ndef is_graph_json_path(p: str | Path) -> bool:\n    return Path(p).resolve().suffix == \".json\"","typeGuard":"def is_loadable_graph_path(p: str | Path) -> bool:\n    rp = Path(p).resolve()\n    return rp.suffix == \".json\" and rp.is_file()","tryCatchPattern":"try:\n    G = _load_graph(p)\nexcept ValueError as e:\n    if \"must be a .json file\" in str(e):\n        p = convert_to_nodelink_json(p)  # e.g. nx.read_graphml -> node_link_data -> json\n        G = _load_graph(p)\n    else:\n        raise","preventionTips":["Always pass graphify-out/graph.json (node-link JSON), not the directory or other formats.","Convert GraphML/GML/JSONL graphs to node-link JSON before loading.","In CLI wrappers, validate the suffix before invoking the loader."],"tags":["graph","validation","file-format"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}