fix(workflow): clear nextStepIds when converting a step to If/Else (#23714)

## Context

Fixes #22947.

A workflow with If/Else branches could fail at runtime with `Step not
found` (and no detail in the Runs panel) because of dangling
`nextStepIds` in the workflow graph — references to steps that no longer
exist.

## Root cause

An If/Else routes only through `settings.input.branches[].nextStepIds`;
its top-level `nextStepIds` is never read by the executor and must stay
empty. But converting an existing step into an If/Else copied the
previous step's `nextStepIds` onto the new If/Else, leaving a stray
top-level reference. That reference is invisible to the executor, and
when steps around it are later deleted it becomes dangling and
propagates into a normal step's `nextStepIds`, which the executor then
tries to follow — `Step not found`.

## Fix

When a step's type is changed to If/Else, don't carry over the previous
step's `nextStepIds`. One change in
`workflow-version-step-update.workspace-service.ts`.

## Verification

Reproduced on a local instance via the editor's GraphQL mutations (build
`trigger → P → X → D`, convert X to If/Else, delete D then X):
- Before: converting X produced a stray `nextStepIds: [D]`, and after
the deletes P was left with a dangling reference.
- After: converting X yields `nextStepIds: []`, and P stays clean — no
dangling reference.
This commit is contained in:
Thomas Trompette
2026-08-03 18:17:02 +02:00
committed by GitHub
parent 62c1cf78af
commit 9e2c870574
2 changed files with 21 additions and 1 deletions
@@ -0,0 +1,16 @@
import { isWorkflowIfElseAction } from 'src/modules/workflow/workflow-executor/workflow-actions/if-else/guards/is-workflow-if-else-action.guard';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
export const getNextStepIdsForStepTypeChange = ({
existingStep,
builtStep,
}: {
existingStep: WorkflowAction;
builtStep: WorkflowAction;
}): string[] | undefined => {
if (isWorkflowIfElseAction(builtStep)) {
return [];
}
return existingStep.nextStepIds;
};
@@ -8,6 +8,7 @@ import {
WorkflowVersionStepExceptionCode,
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
import { getNextStepIdsForStepTypeChange } from 'src/modules/workflow/workflow-builder/workflow-version-step/utils/get-next-step-ids-for-step-type-change.util';
import { WorkflowVersionStepHelpersWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-helpers.workspace-service';
import { WorkflowVersionStepOperationsWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
@@ -133,7 +134,10 @@ export class WorkflowVersionStepUpdateWorkspaceService {
step: {
...builtStep,
id: existingStep.id,
nextStepIds: existingStep.nextStepIds,
nextStepIds: getNextStepIdsForStepTypeChange({
existingStep,
builtStep,
}),
position: existingStep.position,
},
workspaceId,