diff --git a/.changeset/fn-7041-workflow-step-definition-not-found.md b/.changeset/fn-7041-workflow-step-definition-not-found.md new file mode 100644 index 0000000000..46a190af76 --- /dev/null +++ b/.changeset/fn-7041-workflow-step-definition-not-found.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Fix task Workflow tab showing "Step definition not found." for Code Review and other optional steps. +category: fix +dev: WorkflowResultsTab configuredSteps now shows the not-found message only when a step id is absent from the step lookup, not when a found optional-group step has an empty description. diff --git a/packages/dashboard/app/components/WorkflowResultsTab.tsx b/packages/dashboard/app/components/WorkflowResultsTab.tsx index 3e711c57c1..e2f297a8a6 100644 --- a/packages/dashboard/app/components/WorkflowResultsTab.tsx +++ b/packages/dashboard/app/components/WorkflowResultsTab.tsx @@ -595,13 +595,20 @@ export function WorkflowResultsTab({ } }, [canEdit]); + /* + FNXC:WorkflowSettings 2026-06-25-16:20: + Optional-group steps such as Code Review and Browser Verification are valid configured workflow steps but intentionally carry an empty description from the resolver. Show "Step definition not found." only when the step id is genuinely absent from the lookup, never for a found step whose description is empty. + */ const configuredSteps = useMemo(() => { return selectedWorkflowSteps.map((stepId) => { const stepInfo = workflowStepLookup.get(stepId); + const isMissingStepDefinition = stepInfo === undefined; return { id: stepId, name: stepInfo?.name || stepId, - description: stepInfo?.description || t("app:workflow.stepDefinitionNotFound", "Step definition not found."), + description: isMissingStepDefinition + ? t("app:workflow.stepDefinitionNotFound", "Step definition not found.") + : stepInfo.description, phase: stepInfo?.phase || "pre-merge", } as WorkflowStepOption; }); diff --git a/packages/dashboard/app/components/__tests__/WorkflowResultsTab.test.tsx b/packages/dashboard/app/components/__tests__/WorkflowResultsTab.test.tsx index 2f7371135d..324afc5df2 100644 --- a/packages/dashboard/app/components/__tests__/WorkflowResultsTab.test.tsx +++ b/packages/dashboard/app/components/__tests__/WorkflowResultsTab.test.tsx @@ -745,6 +745,42 @@ describe("WorkflowResultsTab", () => { expect(screen.getByText("Pre-merge steps run after implementation, before merge. Post-merge steps run after merge succeeds.")).toBeInTheDocument(); }); + it("shows found optional-group steps with empty descriptions without the missing-definition fallback", async () => { + mockedFetchWorkflowOptionalSteps.mockResolvedValueOnce([ + { + templateId: "code-review", + name: "Code Review", + description: "", + phase: "pre-merge", + defaultOn: true, + }, + ]); + + render( + , + ); + + const configuredStep = await screen.findByTestId("workflow-configured-step-code-review"); + await waitFor(() => expect(configuredStep).toHaveTextContent("Code Review")); + expect(screen.getByTestId("workflow-configured-phase-code-review")).toHaveTextContent("Pre-merge"); + expect(within(configuredStep).queryByText("Step definition not found.")).not.toBeInTheDocument(); + + fireEvent.click(screen.getByTestId("workflow-steps-edit-toggle")); + + const checkboxStep = await screen.findByTestId("workflow-step-checkbox-code-review"); + expect(checkboxStep).toHaveTextContent("Code Review"); + expect(within(checkboxStep).queryByText("Step definition not found.")).not.toBeInTheDocument(); + + const orderStep = screen.getByTestId("workflow-step-order-item-code-review"); + expect(orderStep).toHaveTextContent("Code Review"); + expect(within(orderStep).queryByText("Step definition not found.")).not.toBeInTheDocument(); + }); + it("falls back to step ID and default description when definition is missing", () => { render(