fix: prevent duplicate chatflow creation on repeated save clicks#6553
fix: prevent duplicate chatflow creation on repeated save clicks#6553putramkti wants to merge 1 commit into
Conversation
Guard handleSaveFlow with a loading check so rapid clicks cannot queue multiple create requests. Disable the save button in CanvasHeader while a save is in progress. Fixes FlowiseAI#6502
There was a problem hiding this comment.
Code Review
This pull request introduces guards and UI-level disabling to prevent duplicate or concurrent saving of chatflows by checking the createNewChatflowApi.loading state and passing it as isSaving to the CanvasHeader. The feedback recommends extending these guards to also check for updateChatflowApi.loading (and getHasChatflowChangedApi.loading where applicable) to ensure that updating existing flows is similarly protected against concurrent requests.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| } | ||
|
|
||
| const handleSaveFlow = (chatflowName) => { | ||
| if (createNewChatflowApi.loading) return |
There was a problem hiding this comment.
The current guard only checks createNewChatflowApi.loading, which prevents duplicate requests when creating a new flow. However, if the user is updating an existing flow, updateChatflowApi is used instead. To prevent concurrent update requests, we should guard against both loading states.
| if (createNewChatflowApi.loading) return | |
| if (createNewChatflowApi.loading || updateChatflowApi.loading) return |
| <CanvasHeader | ||
| chatflow={chatflow} | ||
| handleSaveFlow={handleSaveFlow} | ||
| isSaving={createNewChatflowApi.loading} |
There was a problem hiding this comment.
| } | ||
|
|
||
| const handleSaveFlow = async (chatflowName) => { | ||
| if (createNewChatflowApi.loading) return |
There was a problem hiding this comment.
Similar to the agentflow canvas, the guard here should also prevent concurrent saves when updating an existing flow. Since the update flow in this canvas involves checking if the chatflow has changed first, we should guard against createNewChatflowApi.loading, updateChatflowApi.loading, and getHasChatflowChangedApi.loading.
| if (createNewChatflowApi.loading) return | |
| if (createNewChatflowApi.loading || updateChatflowApi.loading || getHasChatflowChangedApi.loading) return |
| <CanvasHeader | ||
| chatflow={chatflow} | ||
| handleSaveFlow={handleSaveFlow} | ||
| isSaving={createNewChatflowApi.loading} |
There was a problem hiding this comment.
Problem
Rapidly clicking the Save button on the canvas (or pressing the keyboard shortcut multiple times) fires multiple concurrent
createNewChatflowAPI calls, resulting in duplicate chatflows being created. This affects both the regular canvas and the AgentFlow V2 canvas.Fix
Add a loading-state guard at three levels to prevent re-entrant save operations:
handleSaveFlowin bothCanvasandAgentflowCanvas— early-return if a save request is already in flightCanvasHeader— receiveisSavingprop, disable the save button visually, and guard bothonSaveChatflowClickandonConfirmSaveNamehandlersconst handleSaveFlow = (chatflowName) => { + if (createNewChatflowApi.loading) return if (reactFlowInstance) { ... } }Scope
packages/ui/src/views/canvas/index.jsx(modified, +2/-0)packages/ui/src/views/canvas/CanvasHeader.jsx(modified, +4/-2)packages/ui/src/views/agentflowsv2/Canvas.jsx(modified, +2/-0)Testing