elsa-workflows/elsa-core · error
Workflow instance not found
Error message
Workflow instance not found
What it means
Thrown by BackgroundActivityInvoker.ExecuteAsync when the workflow instance referenced by the scheduled background activity (ScheduledBackgroundActivity.WorkflowInstanceId) cannot be loaded via IWorkflowInstanceManager.FindByIdAsync. The background invoker resumes a bookmarked activity of an existing instance; if the instance row is gone (deleted, pruned by retention, or never existed), it cannot proceed.
Solutions
- Check that the workflow instance ID in the scheduled activity exists (workflowInstanceManager.FindByIdAsync or the instances API); if it was deleted intentionally, discard the stale queue message.
- Verify the background worker connects to the same database/tenant that owns the instance (connection string / tenant mismatch is common).
- Review retention or cleanup jobs: order deletions after all queued background activities for the instance are drained.
- Re-run or re-trigger the workflow if the instance was lost and the message is unrecoverable; make queue consumers idempotent for missing instances.
Example fix
// before: blindly queue and resume
await workflowInboxManager.SubmitAsync(new NewWorkflowInboxMessage { ... });
// after: skip resume when the instance no longer exists
var instance = await workflowInstanceManager.FindByIdAsync(instanceId, ct);
if (instance == null)
{
logger.LogWarning("Skipping background activity for missing instance {InstanceId}", instanceId);
return;
} Defensive patterns
Strategy: try-catch
Validate before calling
var instance = await workflowInstanceManager.FindByIdAsync(workflowInstanceId, ct);
if (instance is null)
{
logger.LogWarning("Background activity for workflow instance {InstanceId} skipped: instance not found.", workflowInstanceId);
return;
} Type guard
if (workflowInstance is null) return; // narrow after FindByIdAsync before using instance
Try / catch
try
{
await backgroundActivityInvoker.ExecuteAsync(scheduledBackgroundActivity, ct);
}
catch (Exception ex) when (ex.Message == "Workflow instance not found")
{
logger.LogWarning(ex, "Dropping background activity {ActivityId}: instance {InstanceId} no longer exists.",
scheduledBackgroundActivity.Id, scheduledBackgroundActivity.WorkflowInstanceId);
} Prevention
- Ensure retention/cleanup jobs delete instances only after their queued background activities are drained.
- Point background workers at the same database and tenant as the workflow runtime that queued the activity.
- Make background activity consumers idempotent and tolerant of stale queue messages.
- Monitor for this error as a signal of purge jobs racing live workflow execution.
When it happens
Trigger: A queued background activity (e.g. from a workflow executor queue such as DispatchWorkflow's background dispatch) executes after the workflow instance was deleted or never persisted; the ID in the message is stale or from another environment/database.
Common situations: Retention/cleanup jobs deleting finished or stale instances while background work is still queued; manually purging instances from the database; running queue messages across environments sharing a queue but not the instance store; crash-recovery replays referencing instances removed during cleanup.
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 definition 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/154777e3b4d8bcd9.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Runtime/Services/BackgroundActivityInvoker.cs:31
IBookmarkQueue bookmarkQueue,
IWorkflowInstanceManager workflowInstanceManager,
IWorkflowDefinitionService workflowDefinitionService,
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)View on GitHub (pinned to fe9217bdfa)