From 35ce5247c265ab1625a9c9049dc1b5225b75bfa1 Mon Sep 17 00:00:00 2001 From: suhaniiz Date: Mon, 6 Jul 2026 23:56:53 +0530 Subject: [PATCH] fix: resolve state mutation by cloning graph before json conversion in save_graph (#796) --- backend/app/rag/graph_builder.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/backend/app/rag/graph_builder.py b/backend/app/rag/graph_builder.py index 8e2a0f0e..cf22a2ec 100644 --- a/backend/app/rag/graph_builder.py +++ b/backend/app/rag/graph_builder.py @@ -129,26 +129,21 @@ def build_graph(chunks: List[Dict[str, Any]]) -> nx.Graph: chunks={chunk_index}, ) - _convert_sets_for_json(graph) + # REMOVED: _convert_sets_for_json(graph) is removed from here + # so the graph keeps its native Python sets in memory. return graph -def _convert_sets_for_json(graph: nx.Graph) -> None: - for _, data in graph.nodes(data=True): - data["pages"] = sorted(item for item in data.get("pages", []) if item is not None) - data["chunks"] = sorted(item for item in data.get("chunks", []) if item is not None) - - for _, _, data in graph.edges(data=True): - data["pages"] = sorted(item for item in data.get("pages", []) if item is not None) - data["chunks"] = sorted(item for item in data.get("chunks", []) if item is not None) - - def save_graph(graph: nx.Graph, user_id: str, document_id: str) -> Path: """Persist a graph to disk as node-link JSON.""" graph_path = get_graph_path(user_id, document_id) graph_path.parent.mkdir(parents=True, exist_ok=True) - data = nx.node_link_data(graph) + # Create a shallow copy of the graph so we don't mutate the original in memory + export_graph = graph.copy() + _convert_sets_for_json(export_graph) + + data = nx.node_link_data(export_graph) data["metadata"] = { "user_id": user_id, "document_id": document_id,