Graphify-Labs/graphify · error · ValueError
deduplicate_entities: nodes span multiple repos {sorted(repo
Error message
deduplicate_entities: nodes span multiple repos {sorted(repos_seen)!r}. Cross-project dedup is disabled — run dedup per-repo before merging. What it means
Graph-existence preflight in the /graphify path command of the devin fragment (tools/skillgen/fragments/core/devin.md:1196). Shortest-path traversal needs graphify-out/graph.json (loaded via json_graph.node_link_graph(data, edges='links')); the guard exits 1 up front when the file is absent.
Source
Thrown at graphify/dedup.py:489
"""Deduplicate near-identical entities in a knowledge graph.
Args:
nodes: list of node dicts with at minimum {"id": str, "label": str}
edges: list of edge dicts with {"source": str, "target": str, ...}
communities: mapping of node_id -> community_id (from cluster())
dedup_llm_backend: if set, use LLM to resolve ambiguous pairs
root: scan root; ID-collision ranking judges source paths relative to
it so path form and checkout location cannot flip the survivor (#2532)
Returns:
(deduped_nodes, deduped_edges) with edges rewired to survivors
"""
# Guard: cross-project dedup is not supported — nodes from different repos
# share label names by coincidence and must never be merged by string similarity.
# If you need to dedup a global graph, run deduplicate_entities per-repo first.
repos_seen = {n.get("repo") for n in nodes if n.get("repo")}
if len(repos_seen) > 1:
raise ValueError(
f"deduplicate_entities: nodes span multiple repos {sorted(repos_seen)!r}. "
f"Cross-project dedup is disabled — run dedup per-repo before merging."
)
if len(nodes) <= 1:
return nodes, edges
# Resolve the scan root once: _collision_rank ranks each node's source_file
# relative to it, so an absolute stored path and its repo-relative twin rank
# identically and lifecycle markers in the checkout location's own segments
# cannot flip the survivor (#2532).
try:
root_resolved: Path | None = Path(root).resolve() if root else None
except Exception:
root_resolved = None
# Pre-deduplicate: one node per ID. The survivor is the node that *defines* the
# ID (its source_file is the file the ID encodes), not merely the first seen —View on GitHub (pinned to 7fe58b0b0f)
Solutions
- Build the graph with /graphify <path> before running path queries.
- Verify cwd is the directory holding graphify-out/graph.json.
- Fix any earlier build failure so graph.json actually gets written.
- Rebuild if the graph output was cleaned.
Example fix
# before /graphify path router handler # ERROR: No graph found ... # after /graphify . /graphify path router handler
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
if not Path('graphify-out/graph.json').is_file():
raise SystemExit('no graph - run /graphify <path> before path queries')
print('ok') Prevention
- Preflight before every /graphify path invocation.
- Build first in fresh workspaces.
- Verify cwd contains graphify-out/.
- Rebuild after cleanup.
When it happens
Trigger: Running /graphify path between two concepts in a workspace where graphify-out/graph.json does not exist — never built, wrong cwd, deleted, or a failed prior build never reached export.
Common situations: Querying a fresh clone; relative-path miss because the agent runs in a subdirectory; cleanup removed graphify-out/; previous build failed at extraction or shrink guard.
Related errors
- graph.json contains 0 nodes
- graph.json {p} is {size} bytes, exceeds {_MERGE_MAX_BYTES}-b
- Cannot parse {json_path}: {exc}. The file may be corrupted —
- file_hash requires a file, got: {p}
- graphify output not found: {paths['graph']}. Run graphify fi
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/fef0ee32e13a7d8a.
Report an issue: GitHub.