elsa-workflows/elsa-core · error
Workflow definition not found
Error message
Workflow definition not found
What it means
Thrown by BackgroundActivityInvoker.ExecuteAsync when the workflow instance was found but its definition graph cannot be resolved: workflowDefinitionService.FindWorkflowGraphAsync(workflowInstance.DefinitionVersionId) returned null. The instance's DefinitionVersionId no longer resolves to a workflow graph, so the background activity cannot be resumed.
Solutions
- Verify the definition referenced by workflowInstance.DefinitionVersionId exists in the same store/tenant the runtime reads from; restore or re-import it if deleted.
- Check host configuration: all required workflow definition providers/features (e.g. management feature, definition store) are registered so FindWorkflowGraphAsync can resolve the ID.
- Confirm the worker uses the same database/connection and tenant as the environment that created the instance.
- If the definition is unrecoverable, terminate/cancel the stale instances and drop their queued background activities instead of resuming them.
Example fix
// before: assuming definitions are always present
var workflow = await workflowDefinitionService.FindWorkflowGraphAsync(instance.DefinitionVersionId, ct);
// after: keep definitions and instances together; guard before scheduling background work
var graph = await workflowDefinitionService.FindWorkflowGraphAsync(instance.DefinitionVersionId, ct);
if (graph == null)
throw new InvalidOperationException($"Definition {instance.DefinitionVersionId} missing for instance {instance.Id}; restore the definition before resuming."); Defensive patterns
Strategy: try-catch
Validate before calling
var graph = await workflowDefinitionService.FindWorkflowGraphAsync(workflowInstance.DefinitionVersionId, ct);
if (graph is null)
{
logger.LogWarning("Definition {DefinitionVersionId} for instance {InstanceId} is missing; cannot resume background activity.",
workflowInstance.DefinitionVersionId, workflowInstance.Id);
return;
} Type guard
if (workflow is null) throw new InvalidOperationException($"Definition {workflowInstance.DefinitionVersionId} not resolvable for instance {workflowInstance.Id}."); Try / catch
try
{
await backgroundActivityInvoker.ExecuteAsync(scheduledBackgroundActivity, ct);
}
catch (Exception ex) when (ex.Message == "Workflow definition not found")
{
logger.LogWarning(ex, "Cannot resume background activity {ActivityId}: definition {DefinitionVersionId} is unavailable.",
scheduledBackgroundActivity.Id, definitionVersionId);
} Prevention
- Never delete workflow definitions or versions while instances referencing them are still running; cancel instances first.
- Deploy definitions together with the instance data when copying between environments.
- Register all workflow definition providers/features in every host that runs background activity invokers.
- Verify tenant/definition store configuration matches between instance creation and background execution.
When it happens
Trigger: The workflow definition (or the specific version) referenced by the stored instance's DefinitionVersionId was deleted; the definition service/provider backing the lookup is not registered or points at a different store; the definition ID stored on the instance is from another environment.
Common situations: Deleting or re-importing workflow definitions while instances are still running; database/tenant mismatch between the instance store and the definition store; missing workflow definition provider registration in the host; staging data copied partially (instances without their definitions).
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
- Workflow instance not found
- No published version of workflow definition with ID
- No published version of workflow definition with ID
- Cannot deserialize to .
- Failed to deserialize
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/699b6db2741a1b03.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Runtime/Services/BackgroundActivityInvoker.cs:34
IVariablePersistenceManager variablePersistenceManager,
IActivityInvoker activityInvoker,
IActivityPropertyLogPersistenceEvaluator activityPropertyLogPersistenceEvaluator,
WorkflowHeartbeatGeneratorFactory workflowHeartbeatGeneratorFactory,
IServiceProvider serviceProvider,
ILogger<BackgroundActivityInvoker> logger)
: IBackgroundActivityInvoker
{
private readonly ILogger _logger = logger;
/// <inheritdoc />
public async Task ExecuteAsync(ScheduledBackgroundActivity scheduledBackgroundActivity, CancellationToken cancellationToken = default)
{
var workflowInstanceId = scheduledBackgroundActivity.WorkflowInstanceId;
var workflowInstance = await workflowInstanceManager.FindByIdAsync(workflowInstanceId, cancellationToken);
if (workflowInstance == null) throw new("Workflow instance not found");
var workflowState = workflowInstance.WorkflowState;
var workflow = await workflowDefinitionService.FindWorkflowGraphAsync(workflowInstance.DefinitionVersionId, cancellationToken);
if (workflow == null) throw new("Workflow definition not found");
var workflowExecutionContext = await WorkflowExecutionContext.CreateAsync(serviceProvider, workflow, workflowState, cancellationToken: cancellationToken);
var activityNodeId = scheduledBackgroundActivity.ActivityNodeId;
var activityExecutionContext = workflowExecutionContext.ActivityExecutionContexts.First(x => x.NodeId == activityNodeId);
using (workflowHeartbeatGeneratorFactory.CreateHeartbeatGenerator(workflowExecutionContext))
{
await variablePersistenceManager.LoadVariablesAsync(workflowExecutionContext);
activityExecutionContext.SetIsBackgroundExecution();
await activityInvoker.InvokeAsync(activityExecutionContext);
await variablePersistenceManager.SaveVariablesAsync(workflowExecutionContext);
}
await ResumeWorkflowAsync(activityExecutionContext, scheduledBackgroundActivity);
}
private async Task ResumeWorkflowAsync(ActivityExecutionContext activityExecutionContext, ScheduledBackgroundActivity scheduledBackgroundActivity)
{
var cancellationToken = activityExecutionContext.CancellationToken;
var activityNodeId = scheduledBackgroundActivity.ActivityNodeId;View on GitHub (pinned to fe9217bdfa)