Graphify-Labs/graphify · error · ValueError
Graph path must be a .json file, got: {graph_path!r}
Error message
Graph path must be a .json file, got: {graph_path!r} What it means
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.
Source
Thrown at graphify/serve.py:29
import threading
from typing import NamedTuple
import networkx as nx
from networkx.readwrite import json_graph
from graphify.security import sanitize_label, check_graph_file_size_cap
from graphify.build import edge_data, edge_datas
from graphify.paths import default_graph_json as _default_graph_json
try:
import jieba as _jieba # type: ignore[import-untyped]
except ImportError:
_jieba = None
def _load_graph(graph_path: str) -> nx.Graph:
try:
resolved = Path(graph_path).resolve()
if resolved.suffix != ".json":
raise ValueError(f"Graph path must be a .json file, got: {graph_path!r}")
if not resolved.exists():
raise FileNotFoundError(f"Graph file not found: {resolved}")
check_graph_file_size_cap(resolved)
safe = resolved
data = json.loads(safe.read_text(encoding="utf-8"))
if "links" not in data and "edges" in data:
data = dict(data, links=data["edges"])
# Stash the on-disk logical flag before the load-time override below:
# `directed: True` exists only so renderers can recover stored arc
# order (#2309); tools that care about logical direction (#2487) must
# not mistake the override for graph truth.
_logical_directed = bool(data.get("directed", False))
data = {**data, "directed": True}
try:
from graphify.build import graph_has_legacy_ids as _legacy
if _legacy(data.get("nodes", [])):
print(
"[graphify] note: this graph uses the pre-#1504 node-ID scheme; "View on GitHub (pinned to 7fe58b0b0f)
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.
Example fix
# before
G = _load_graph("graphify-out") # directory
G = _load_graph("data/graph.graphml") # wrong format
# after
G = _load_graph("graphify-out/graph.json") Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
def is_graph_json_path(p: str | Path) -> bool:
return Path(p).resolve().suffix == ".json" Type guard
def is_loadable_graph_path(p: str | Path) -> bool:
rp = Path(p).resolve()
return rp.suffix == ".json" and rp.is_file() Try / catch
try:
G = _load_graph(p)
except ValueError as e:
if "must be a .json file" in str(e):
p = convert_to_nodelink_json(p) # e.g. nx.read_graphml -> node_link_data -> json
G = _load_graph(p)
else:
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Extraction JSON has {len(errors)} error(s):
- Google Workspace shortcut {path} does not include a Drive fi
- ingest: {exc}
- outcome must be one of {OUTCOMES}, got {outcome!r}
- Unknown backend {backend!r}. Available: {sorted(BACKENDS)}
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/e6bfc56ddc843ab9.
Report an issue: GitHub.