{"record":{"id":"12c84f0f7c54b3a9","repo":"OrchardCMS/OrchardCore","slug":"workflow-with-id-workflowtype-id-does-not-have-a-start","errorCode":null,"errorMessage":"Workflow with ID {workflowType.Id} does not have a start activity.","messagePattern":"Workflow with ID (.+?) does not have a start activity\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.Workflows/Services/WorkflowManager.cs","lineNumber":299,"sourceCode":"\n        if (workflowContext.Status == WorkflowStatus.Finished && workflowType.DeleteFinishedWorkflows)\n        {\n            await _workflowStore.DeleteAsync(workflowContext.Workflow);\n        }\n        else\n        {\n            await PersistAsync(workflowContext);\n        }\n\n        return workflowContext;\n    }\n\n    public async Task<WorkflowExecutionContext> RestartWorkflowAsync(WorkflowType workflowType, IDictionary<string, object> input = null, string correlationId = null)\n    {\n        ArgumentNullException.ThrowIfNull(workflowType);\n\n        var startActivity = workflowType.Activities?.FirstOrDefault(x => x.IsStart)\n            ?? throw new InvalidOperationException($\"Workflow with ID {workflowType.Id} does not have a start activity.\");\n\n        // Create a new workflow instance.\n        var workflow = NewWorkflow(workflowType, correlationId);\n\n        // Create a workflow context.\n        var workflowContext = await CreateWorkflowExecutionContextAsync(workflowType, workflow, input);\n        workflowContext.Status = WorkflowStatus.Starting;\n\n        // Signal every activity that the workflow is about to start.\n        // This should be called prior OnInputReceivedAsync.\n        await InvokeActivitiesAsync(workflowContext, x => x.Activity.OnWorkflowRestartingAsync(workflowContext, workflowContext.CancellationToken));\n\n        // Signal every activity about available input.\n        await InvokeActivitiesAsync(workflowContext, x => x.Activity.OnInputReceivedAsync(workflowContext, input));\n\n        if (workflowContext.CancellationToken.IsCancellationRequested)\n        {\n            return workflowContext;","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Workflows/Services/WorkflowManager.cs#L281-L317","documentation":"RestartWorkflowAsync starts a NEW workflow instance of the given type and must begin execution at the type's designated start activity. The method requires workflowType.Activities to contain an activity with IsStart == true; if none exists it throws InvalidOperationException, because a restarted workflow has no entry point and could never run.","triggerScenarios":"Calling IWorkflowManager.RestartWorkflowAsync (directly or via the workflow restart admin/API path) for a workflow type whose activity list is empty or whose activities all have IsStart == false — e.g. the start activity was deleted in the editor, the workflow type definition was saved in a broken state, or activities were not loaded from storage.","commonSituations":"Admin 'Restart' action on a workflow type whose start event (e.g. a SignalEvent or trigger) was removed; corrupted or partially imported workflow type definitions; a bug in custom code that clears the Activities collection before calling RestartWorkflowAsync; deserialization where IsStart flags were lost.","solutions":["Open the workflow type definition in the admin UI and re-add a start activity (an event such as a signal/trigger) so exactly one activity has IsStart = true, then retry the restart.","Check workflowType.Activities and IsStart flags in code before calling RestartWorkflowAsync and refuse to call it when no start activity exists.","If the definition is corrupted, recreate or re-import the workflow type from a known-good recipe/export.","If activities exist but IsStart is false due to a storage/import bug, patch the stored WorkflowType document to mark the intended start activity."],"exampleFix":"// before\nvar wfType = await workflowTypeStore.GetAsync(id);\nawait workflowManager.RestartWorkflowAsync(wfType); // throws if no IsStart activity\n// after\nvar wfType = await workflowTypeStore.GetAsync(id);\nif (wfType?.Activities?.Any(a => a.IsStart) == true)\n{\n    await workflowManager.RestartWorkflowAsync(wfType);\n}","handlingStrategy":"validation","validationCode":"// before restart\nArgumentNullException.ThrowIfNull(workflowType);\nif (workflowType.Activities?.Any(a => a.IsStart) != true)\n    throw new InvalidOperationException($\"Workflow type '{workflowType.Id}' has no start activity; cannot restart.\");","typeGuard":"static bool HasStartActivity(WorkflowType t) => t?.Activities?.Any(a => a.IsStart) == true;","tryCatchPattern":"try { await workflowManager.RestartWorkflowAsync(workflowType, input, correlationId); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not have a start activity\"))\n{ logger.LogError(ex, \"Workflow type {Id} lacks a start activity\", workflowType.Id); /* notify admin to fix definition */ }","preventionTips":["Never delete the start event from a workflow type without replacing it first","Validate workflow type definitions (one IsStart activity) before saving or importing","Add a pre-restart check for a start activity in custom admin actions","Re-export/recreate corrupted workflow types from known-good recipes"],"tags":["workflows","invalid-state","missing-start-activity","orchardcore"],"backgroundTag":"invalid-state-transition","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}