From ef0e6ee681146e7a9fab3b9ec52d4bb8e5b41c33 Mon Sep 17 00:00:00 2001 From: Ahmad Fathallah Date: Tue, 12 May 2026 02:37:38 +0300 Subject: [PATCH] harden community serialization fallbacks Use safe JSON serialization fallbacks for deterministic sort keys in clustering and graph canonicalization, and skip invalid community IDs with a stderr warning instead of raising during update rebuilds. Co-authored-by: Cursor --- graphify/cluster.py | 6 +++++- graphify/watch.py | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/graphify/cluster.py b/graphify/cluster.py index b1f1df299..7959ec173 100644 --- a/graphify/cluster.py +++ b/graphify/cluster.py @@ -32,7 +32,11 @@ def _partition(G: nx.Graph) -> dict[str, int]: stable.add_nodes_from(sorted(G.nodes(), key=str)) edge_rows = sorted( G.edges(data=True), - key=lambda row: (str(row[0]), str(row[1]), json.dumps(row[2], sort_keys=True, ensure_ascii=False)), + key=lambda row: ( + str(row[0]), + str(row[1]), + json.dumps(row[2], sort_keys=True, ensure_ascii=False, default=str), + ), ) for src, tgt, attrs in edge_rows: stable.add_edge(src, tgt, **attrs) diff --git a/graphify/watch.py b/graphify/watch.py index c1cdee419..7c5dca639 100644 --- a/graphify/watch.py +++ b/graphify/watch.py @@ -123,7 +123,15 @@ def _node_community_map(graph_data: dict) -> dict[str, int]: cid = node.get("community") if node_id is None or cid is None: continue - out[str(node_id)] = int(cid) + try: + out[str(node_id)] = int(cid) + except (TypeError, ValueError): + print( + f"[graphify watch] Skipping node with invalid community id: " + f"node_id={node_id!r} community={cid!r}", + file=sys.stderr, + ) + continue return out @@ -134,7 +142,7 @@ def _canonical_graph_for_compare(graph_data: dict) -> dict: if key in canonical and isinstance(canonical[key], list): canonical[key] = sorted( canonical[key], - key=lambda item: json.dumps(item, sort_keys=True, ensure_ascii=False), + key=lambda item: json.dumps(item, sort_keys=True, ensure_ascii=False, default=str), ) return canonical