From 79748ca7fa7f4ebcd9d286e7f2ba8a4c4154f47d Mon Sep 17 00:00:00 2001 From: Otto Date: Sat, 14 Feb 2026 19:40:08 +0000 Subject: [PATCH] fix: avoid history pollution in addLinks by bulk-adding edges Changed addLinks to collect all valid edges first and add them in a single set() call with one history push, instead of calling addEdge for each link which would push to history for every edge individually. Fixes: Sentry bug prediction about undo/redo history pollution --- .../app/(platform)/build/stores/edgeStore.ts | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/autogpt_platform/frontend/src/app/(platform)/build/stores/edgeStore.ts b/autogpt_platform/frontend/src/app/(platform)/build/stores/edgeStore.ts index 74bf67820a..3688217a38 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/stores/edgeStore.ts +++ b/autogpt_platform/frontend/src/app/(platform)/build/stores/edgeStore.ts @@ -139,16 +139,45 @@ export const useEdgeStore = create((set, get) => ({ // Get current node IDs to validate links const nodeIds = new Set(useNodeStore.getState().nodes.map((n) => n.id)); - links.forEach((link) => { + // Convert and filter links in one pass, avoiding individual addEdge calls + // which would push to history for each edge (causing history pollution) + const newEdges: CustomEdge[] = []; + const existingEdges = get().edges; + + for (const link of links) { // Skip invalid links (orphan edges referencing non-existent nodes) if (!nodeIds.has(link.source_id) || !nodeIds.has(link.sink_id)) { console.warn( `[EdgeStore] Skipping invalid link: source=${link.source_id}, sink=${link.sink_id} - node(s) not found`, ); - return; + continue; } - get().addEdge(linkToCustomEdge(link)); - }); + + const edge = linkToCustomEdge(link); + + // Skip if edge already exists + const exists = existingEdges.some( + (e) => + e.source === edge.source && + e.target === edge.target && + e.sourceHandle === edge.sourceHandle && + e.targetHandle === edge.targetHandle, + ); + if (!exists) { + newEdges.push(edge); + } + } + + if (newEdges.length > 0) { + // Bulk add all edges at once, pushing to history only once + const prevState = { + nodes: useNodeStore.getState().nodes, + edges: existingEdges, + }; + + set((state) => ({ edges: [...state.edges, ...newEdges] })); + useHistoryStore.getState().pushState(prevState); + } }, getAllHandleIdsOfANode: (nodeId) =>