elsa-workflows/elsa-core · error · InvalidOperationException
Workflow definition with ID
Error message
Workflow definition with ID '{workflowDefinitionId}' not found. What it means
RunWorkflowExtensions in Elsa.Testing.Shared resolves IWorkflowDefinitionService and calls FindWorkflowGraphAsync with the given definition ID and version options; when no workflow graph is found it throws InvalidOperationException. This means no workflow definition with that ID exists (or none matches the requested version state, e.g. Published when only Draft exists).
Solutions
- Register/import the workflow definition in the test setup before running (e.g. via the workflow definition import/publish API used elsewhere in the test suite).
- Pass an explicit VersionOptions (e.g. VersionOptions.Latest or VersionOptions.SpecificVersion(n)) if the definition is not published.
- Verify the workflowDefinitionId string matches the definition's ID (case and value) as stored.
- Publish the definition if it exists only as a draft and the default Published lookup is intended.
Example fix
// before
await services.RunWorkflowAsync("my-workflow"); // not found: only a draft exists
// after
await services.PopulateRegistriesAsync(); // or import + publish the definition first
await services.RunWorkflowAsync("my-workflow", VersionOptions.Latest); Defensive patterns
Strategy: validation
Validate before calling
// check the definition exists (and matches version state) before running
var defService = services.GetRequiredService<IWorkflowDefinitionService>();
var graph = await defService.FindWorkflowGraphAsync(definitionId, VersionOptions.Published);
if (graph is null)
throw new InvalidOperationException($"Test setup error: definition '{definitionId}' missing or not published. Import/publish it first."); Try / catch
try
{
await services.RunWorkflowAsync(definitionId);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not found"))
{
Assert.Fail($"Workflow definition '{definitionId}' is not registered/published in the test host: {ex.Message}");
} Prevention
- Import and publish workflow definitions in test setup (or use fixtures that do so) before running them.
- Pass explicit VersionOptions matching how the definition was stored (Latest for drafts).
- Reference definition IDs via shared constants instead of inline strings.
- After renaming definitions, update all tests referencing the old ID.
When it happens
Trigger: Calling RunWorkflowAsync(services, "some-id") with an ID that was never registered/imported in the test's workflow definition store; the definition exists only as a Draft but the default VersionOptions.Published is requested; the definition was registered under a different definition ID than the one passed.
Common situations: Tests forget to add the workflow definition to the in-memory store before running; using the workflow's root ID when the store keys by a different identifier (or vice versa); a workflow imported without publishing, while the extension defaults to Published; renames of workflow definitions after tests were written.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Invalid variable test values.
- Signal ' ' was not of type ' '.
- Signal ' ' timed out after milliseconds.
- Build() must be called before accessing services
- AlterationFaultCodes.PlanNotFound
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/0ce086629cec7730.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/Elsa.Testing.Shared.Integration/RunWorkflowExtensions.cs:42
/// Runs a workflow until its end, automatically resuming any bookmark it encounters.
/// </summary>
/// <param name="workflowDefinitionId">The ID of the workflow definition.</param>
/// <param name="input">An optional dictionary of input values.</param>
/// <param name="correlationId">An optional correlation id of the workflow.</param>
/// <param name="versionOptions">An optional set of options to specify the version of the workflow definition to retrieve.</param>
/// <param name="runWorkflowOptions">Optional workflow execution options.</param>
/// <returns>The workflow state.</returns>
public async Task<WorkflowState> RunWorkflowUntilEndAsync(string workflowDefinitionId,
IDictionary<string, object>? input = null,
string? correlationId = null,
VersionOptions? versionOptions = null,
RunWorkflowOptions? runWorkflowOptions = null)
{
var workflowDefinitionService = services.GetRequiredService<IWorkflowDefinitionService>();
var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(workflowDefinitionId, versionOptions ?? VersionOptions.Published);
if (workflowGraph == null)
throw new InvalidOperationException($"Workflow definition with ID '{workflowDefinitionId}' not found.");
var workflowRuntime = services.GetRequiredService<IWorkflowRuntime>();
var workflowClient = await workflowRuntime.CreateClientAsync();
var response = await workflowClient.CreateAndRunInstanceAsync(new()
{
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(workflowGraph.Workflow.Identity.Id),
Input = input,
CorrelationId = correlationId,
Properties = runWorkflowOptions?.Properties
});
var bookmarkStore = services.GetRequiredService<IBookmarkStore>();
// Continue resuming the workflow for as long as there are bookmarks to resume and the workflow is not Finished.
while (response.Status != WorkflowStatus.Finished)
{
var bookmarks = (await bookmarkStore.FindManyAsync(new()
{View on GitHub (pinned to fe9217bdfa)