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

  1. Point the loader at the actual node-link JSON: graphify-out/graph.json.
  2. If your graph is in another format, convert it to node-link JSON (nx.node_link_data) first.
  3. Quote the path and check for shell glob expansion when passing it on the command line.
  4. 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

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


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/e6bfc56ddc843ab9. Report an issue: GitHub.