Skip to content

Instantly share code, notes, and snippets.

@dannon
Created February 24, 2026 13:21
Show Gist options
  • Select an option

  • Save dannon/e59394a124da8e21e10fea2697d7a77d to your computer and use it in GitHub Desktop.

Select an option

Save dannon/e59394a124da8e21e10fea2697d7a77d to your computer and use it in GitHub Desktop.
Triage: galaxyproject/galaxy #21662 - Create New Workflow in Workflow Editor broken

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.

Galaxy Version

Galaxy Version: 25.1 Commit: 38344609a17035ad653923396c815cbb51570796

Reproduction Steps

  1. Edit an existing workflow in the editor
  2. Click + Create New
  3. Sometimes, nothing happens the first time you click it
  4. The same workflow is duplicated in a new editor

Expected Behavior

The existing workflow should be saved (if the user likes) and a blank editor should open.

Screencast

20260126-2241-38.9391072.mp4

Issue #21662: Code Research

Code Path Trace

Entry Points

There are two UI paths that trigger "Create New Workflow":

  1. 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().

  2. 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().

The createNewWorkflow() Method

File: client/src/components/Workflow/Editor/Index.vue, lines 932-935

async createNewWorkflow() {
    await this.saveOrCreate();
    this.$router.push("/workflows/edit");
},

This method:

  1. Saves the current workflow (via saveOrCreate() which calls either onCreate() or onSave() depending on whether the workflow is new).
  2. Navigates to /workflows/edit with NO query parameters (i.e., a new blank workflow).

The Router Handler

File: client/src/entry/analysis/modules/WorkflowEditor.vue

This component wraps the Editor and manages loading workflow data based on URL parameters. It watches $route.params for changes and calls getEditorConfig().

watch: {
    "$route.params": {
        handler() {
            this.getEditorConfig();
        },
        immediate: true,
    },
},

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.

The Route Definition

File: client/src/entry/analysis/router.js, lines 177-181

{
    path: "/workflows/edit",
    component: WorkflowEditorModule,
    redirect: redirectAnon(),
},

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):

async onCreate() {
    const { id, name, number_of_steps } = await this.services.createWorkflow(this);
    this.hasChanges = false;
    this.$emit("skipNextReload");
    await this.routeToWorkflow(id);
    Toast.success(message);
}

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
client/src/entry/analysis/modules/WorkflowEditor.vue Router-level wrapper with route watcher (BUG LOCATION)
client/src/components/Workflow/Editor/modules/activities.ts Activity bar definitions including "Create new"
client/src/components/Panels/WorkflowPanel.vue Side panel with "+" button for creating workflows
client/src/components/Workflow/services.js createWorkflow() service that POSTs to API
client/src/components/Workflow/Editor/modules/model.ts toSimple() serializer used during save
client/src/entry/analysis/router.js Route definition for /workflows/edit
client/src/utils/query-string-parsing.js Query.get() utility used to read URL params

Git History of WorkflowEditor.vue (Relevant)

  • 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)

Issue #21662: Importance Assessment

Severity: Medium (Functional Breakage)

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:

  1. Saving their current workflow
  2. Navigating to the Workflow List page
  3. 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.

User Impact Signals

  • Issue reactions: None reported
  • Duplicate reports: None found
  • Comments: 0 comments on the issue
  • Reporter: ahmedhamidawan (regular Galaxy contributor, credible report)

Recommendation: Next Release

Priority: P2 -- Fix in next release cycle.

Rationale:

  • The bug is real and reproducible, affecting a standard workflow editor action
  • An acceptable workaround exists (create from workflow list page)
  • The fix is straightforward (change watcher target + reset state) with low risk
  • No data loss or security implications
  • Not severe enough for a hotfix given the workaround exists

Issue #21662: Fix Plan

Root Cause

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

File: client/src/entry/analysis/modules/WorkflowEditor.vue

Change line 32 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

File: client/src/entry/analysis/modules/WorkflowEditor.vue

In the getEditorConfig() method, newWorkflow is set to true when no workflow ID is found but is never reset to false. Add a reset:

async getEditorConfig() {
    // ... existing code ...

    this.version = Query.get("version");
    this.storedWorkflowId = Query.get("id");
    this.workflowId = Query.get("workflow_id");
    const workflowId = this.workflowId || this.storedWorkflowId;
    if (!workflowId) {
        this.newWorkflow = true;
        this.storedWorkflowId = null;  // ensure old ID is cleared
        return;
    }

    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.

Affected Files

File Change
client/src/entry/analysis/modules/WorkflowEditor.vue Change watcher target, reset newWorkflow flag

Testing Strategy

Manual Testing

  1. Create new from existing workflow:

    • Open an existing workflow in the editor
    • Click "Create new" in the activity bar
    • Verify: current workflow is saved, a blank editor opens
    • Verify: new editor has no steps, default "Unnamed Workflow" name
  2. 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
  3. Create new from Workflows side panel "+" button:

    • Open the Workflows side panel
    • Click the "+" button
    • Verify: same behavior as above
  4. 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
  5. 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.

Effort Estimate

  • Implementation: ~15 minutes
  • Manual testing: ~30 minutes
  • Total: Under 1 hour

Issue #21662: Triage Summary

Top-line Summary

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

  1. Should the watcher use $route.query (targeted) or $route.fullPath (broader, matching pattern used in other modules like Analysis.vue)?
  2. 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?
  3. Should we add a Selenium test for the "create new from editor" flow to prevent future regressions in this area?
  4. 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment