You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Issue #21662: Create New Workflow in Workflow Editor broken
State: OPEN
Author: ahmedhamidawan
Labels: area/UI-UX, kind/bug
Comments: 0
Projects: Galaxy Dev - weeklies (Triage/Discuss)
Description
The Create New + option in the workflow editor activity bar is broken. Instead of (if needed, saving the current workflow and) creating a blank new workflow, it saves the current one and then creates a new workflow with the same exact steps from the original workflow.
There are two UI paths that trigger "Create New Workflow":
Activity Bar click: The "Create new" activity (id: workflow-create) in client/src/components/Workflow/Editor/modules/activities.ts (line 162-170) is a click: true activity. When clicked, onActivityClicked in Index.vue (line 987-988) calls createNewWorkflow().
Workflow Side Panel "+" button: In client/src/components/Panels/WorkflowPanel.vue (line 146-149, 155-163), the createNew() function emits "createWorkflow", which is caught by Index.vue (line 75) and also calls createNewWorkflow().
This component wraps the Editor and manages loading workflow data based on URL parameters. It watches $route.params for changes and calls getEditorConfig().
getEditorConfig() reads id, workflow_id, and version from the URL query string using Query.get() (which parses window.location.search). If no workflow ID is found, it sets newWorkflow = true and returns early.
This is a flat path with no route parameters. All workflow identification is done via query strings (?id=xxx).
Bug Theories
Theory 1 (Most Probable): $route.params watcher never fires on query-only changes
The WorkflowEditor.vue watcher is on $route.params, but the route /workflows/edit defines NO params. The route path is static. When navigating from /workflows/edit?id=abc123 to /workflows/edit (no query), $route.params is {} in both cases -- it never changes. Therefore the watcher never fires, and getEditorConfig() is never called for the new route.
This means:
storedWorkflowId is never cleared (still holds the previous workflow's ID)
newWorkflow is never set to true
editorReloadKey is never incremented
The Editor component continues showing the previous workflow's data
This perfectly explains both symptoms:
"Sometimes, nothing happens the first time you click it" -- the watcher doesn't fire, no state changes
"The same workflow is duplicated in a new editor" -- the old state persists
Evidence: Every other module in client/src/entry/analysis/modules/ uses :key="$route.fullPath" on the <router-view> to handle this, but WorkflowEditor.vue uses a $route.params watcher instead.
Historical context: The original code (pre-commit 93b382739db) used $route.params with the old /workflow/editor controller endpoint which used a different routing scheme. When the code was refactored in 93b382739db to use the API directly and parse query strings, the watcher was kept on $route.params even though the route only uses query strings.
Theory 2: saveOrCreate() side effects leak into the new workflow
Even if the watcher were fixed, there's a secondary issue. createNewWorkflow() calls saveOrCreate() first, which for new temp workflows calls onCreate(). Inside onCreate() (line 1004-1014):
services.createWorkflow(this) calls toSimple(workflow.id, workflow) which serializes the current workflow state (with all its steps) and POSTs it to /api/workflows. So onCreate saves the CURRENT workflow contents as a new workflow. Then routeToWorkflow(id) navigates to that saved workflow.
After saveOrCreate() returns, createNewWorkflow() does this.$router.push("/workflows/edit"). But if saveOrCreate() called onCreate() which already navigated via routeToWorkflow(id), the subsequent push to /workflows/edit may not trigger properly because of the params-vs-query watcher issue (Theory 1).
For the case where the workflow is already saved (not new temp), saveOrCreate() calls onSave() which saves in place -- this is correct behavior. The subsequent $router.push("/workflows/edit") should open a new blank editor, but doesn't due to Theory 1.
Theory 3: newWorkflow state not being reset between navigations
In WorkflowEditor.vue, newWorkflow is set to true when no workflow ID is found, but is never reset to false. If a user creates a new workflow (setting newWorkflow = true), saves it (which adds ?id=xxx to the URL), and then clicks "Create New" again, the newWorkflow flag is still true from before. Combined with storedWorkflowId still having the old value, the v-if="storedWorkflowId || newWorkflow" condition in the template keeps the old Editor mounted with the old :workflow-id prop and the same :key, so it never re-renders.
Key Files
File
Role
client/src/components/Workflow/Editor/Index.vue
Main editor component with createNewWorkflow() method
e26fb691ff0 - "Fix subworkflow editing" -- moved editorReloadKey increment to after storedWorkflowId assignment
93b382739db - "Drop old load_workflow controller method, use API" -- major refactor that introduced the current code; likely introduced the regression by switching to query-string-based ID reading while keeping $route.params watcher
f4e37c9ed07 - "fix workflow creation" -- added skipNextReload emit for the onCreate() path
8315a04259a - "reload if window is navigated to/from new workflow" -- previous attempt to fix navigation issues with window.history.length heuristic (later removed)
This is a functional breakage of a workflow editor feature. The "Create New" action from within the editor does not work correctly -- it either does nothing or duplicates the current workflow instead of opening a blank editor. No data loss occurs (the original workflow is saved correctly), and no crash or hang is involved.
Blast Radius: All Users
Every user who uses the "Create New" workflow action from within the workflow editor is affected. This includes both:
The "Create new" button in the activity bar options
The "+" button in the Workflows side panel
The bug affects all Galaxy instances running version 25.1+ (post-commit 93b382739db).
Workaround: Acceptable
Users can work around this by:
Saving their current workflow
Navigating to the Workflow List page
Creating a new workflow from the Workflow List page (which uses /workflows/edit directly without the broken routing issue)
This is a minor inconvenience (2-3 extra clicks), not a blocker.
Regression Status: Regression since 25.1-dev
This is a regression introduced by commit 93b382739db ("Drop old load_workflow controller method, use API") authored by mvdbeek. That commit refactored WorkflowEditor.vue to use query string parameters (Query.get("id")) instead of the old controller-based config, but did not update the route watcher from $route.params to $route.query (or $route.fullPath). Since the /workflows/edit route has no route params (only query strings), the watcher never fires when query params change.
Previous commits (8315a04259a, f4e37c9ed07) attempted to fix related navigation issues, indicating this area has been fragile.
The WorkflowEditor.vue component watches $route.params for changes to trigger getEditorConfig(), but the /workflows/edit route uses query strings (?id=xxx), not route params. When navigating from /workflows/edit?id=abc to /workflows/edit (no query), $route.params is {} both times, so the watcher never fires and the editor state is never reset.
Fix Strategy
Primary Fix: Change watcher from $route.params to $route.query
This ensures the watcher fires whenever query parameters change (including when they are removed entirely, as in the "create new" navigation).
Alternative: Watch $route.fullPath instead, which captures both path and query changes. This is what other modules in the same directory use (e.g., Analysis.vue, Admin.vue, Base.vue all use :key="$route.fullPath"). However, $route.query is more precise and appropriate since the handler only cares about query parameter changes.
Secondary Fix: Reset newWorkflow flag when loading an existing workflow
In the getEditorConfig() method, newWorkflow is set to true when no workflow ID is found but is never reset to false. Add a reset:
asyncgetEditorConfig(){// ... existing code ...this.version=Query.get("version");this.storedWorkflowId=Query.get("id");this.workflowId=Query.get("workflow_id");constworkflowId=this.workflowId||this.storedWorkflowId;if(!workflowId){this.newWorkflow=true;this.storedWorkflowId=null;// ensure old ID is clearedreturn;}this.newWorkflow=false;// <-- ADD THIS: reset when loading an existing workflow// ... rest of method ...}
Optional Fix: Clear storedWorkflowId when creating a new workflow
When navigating to /workflows/edit (no query params), storedWorkflowId should be explicitly set to null. The current code does this.storedWorkflowId = Query.get("id") which returns undefined when no id param exists. Since Query.get returns undefined (not null), and the template checks v-if="storedWorkflowId || newWorkflow", this should work -- but explicitly setting it to null makes the intent clearer.
Verify: current workflow is saved, a blank editor opens
Verify: new editor has no steps, default "Unnamed Workflow" name
Create new from new (unsaved) workflow:
Navigate to /workflows/edit (new blank workflow)
Add a few steps
Click "Create new" in the activity bar
Verify: the first workflow is saved/created with its steps
Verify: a new blank editor opens
Create new from Workflows side panel "+" button:
Open the Workflows side panel
Click the "+" button
Verify: same behavior as above
Subworkflow editing still works:
Open a workflow containing a subworkflow
Click to edit the subworkflow
Verify: subworkflow opens in the editor
Verify: changes can be saved
Normal workflow loading still works:
Navigate to workflow list
Click to edit a workflow
Verify: workflow loads correctly in editor
Automated Testing
Check if there's an existing test for createNewWorkflow in client/src/components/Workflow/Editor/Index.test.ts. If not, consider adding a basic test that verifies the navigation call.
The existing Selenium tests in lib/galaxy_test/selenium/test_workflow_editor.py may cover basic editor loading but likely don't test the "create new from within editor" flow.
Risk Assessment
Low risk. The change is minimal (1-2 lines in a single file) and the watcher's handler function getEditorConfig() already correctly handles all cases (existing workflow, new workflow, version-specific loading). The only issue is that the watcher itself isn't firing. Changing the trigger source from $route.params to $route.query doesn't change any logic, just ensures it actually gets called.
The "Create New" workflow action in the editor is broken because WorkflowEditor.vue watches $route.params for navigation changes, but the /workflows/edit route uses query strings (?id=xxx), not route params. Since $route.params is always {} for this route, the watcher never fires when navigating from an existing workflow to a new blank editor. The fix is to change the watcher target from $route.params to $route.query and ensure newWorkflow state is properly reset. This is a one-line fix in client/src/entry/analysis/modules/WorkflowEditor.vue, introduced as a regression in commit 93b382739db when the old controller-based loading was replaced with API-based query string parsing.
Importance Assessment
Dimension
Rating
Severity
Medium -- functional breakage, no data loss
Blast Radius
All users who use "Create New" from within the editor
Workaround
Acceptable -- users can create workflows from the workflow list page
Regression
Yes -- introduced in 25.1-dev by commit 93b382739db
Priority
P2 -- next release (not a hotfix)
Discussion Questions
Should the watcher use $route.query (targeted) or $route.fullPath (broader, matching pattern used in other modules like Analysis.vue)?
The WorkflowEditor.vue component has accumulated complexity from repeated navigation fixes (8315a04259a, f4e37c9ed07, e26fb691ff0). Would it be worth refactoring this to a composition API + useRoute() approach while fixing this bug, or keep it minimal?
Should we add a Selenium test for the "create new from editor" flow to prevent future regressions in this area?
Is this worth backporting to the 25.1 release branch?
Effort and Difficulty
Effort estimate: Under 1 hour total (implementation + manual testing)
Difficulty of fix: Low -- single file, 1-2 line change
Difficulty of reproduction: Easy -- open any workflow in editor, click "Create New"
Difficulty of testing: Low -- straightforward manual verification, though adding automated coverage would take additional time