elsa-workflows/elsa-core · error · Exception

No activity execution context found with the specified ID.

Error message

No activity execution context found with the specified ID.

What it means

When resuming or running a workflow with an activity handle that carries an ActivityInstanceId, WorkflowRunner looks up the matching ActivityExecutionContext in the current execution context to re-schedule it. If no activity execution context with that ID exists in this workflow instance, the handle is dangling and this exception is thrown.

Solutions

  1. Verify the ActivityHandle.ActivityInstanceId belongs to the same workflow instance you are running; reload the correct instance.
  2. Check whether the activity already completed — if so, resume the workflow without an activity handle instead of targeting the finished context.
  3. Re-extract/persist workflow state so the referenced ActivityExecutionContext is present before resuming.
  4. Fall back to scheduling by activity node ID (ActivityHandle by activity ID/path) instead of instance ID when the instance ID may be stale.

Example fix

// before
await runner.RunAsync(instance, new ActivityHandle { ActivityInstanceId = staleId });
// after
var handle = workflowExecutionContext.ActivityExecutionContexts.Any(x => x.Id == staleId)
    ? new ActivityHandle { ActivityInstanceId = staleId }
    : new ActivityHandle { ActivityId = activityNodeId }; // or resume with no handle
Defensive patterns

Strategy: validation

Validate before calling

var handle = new ActivityHandle { ActivityInstanceId = instanceId };
// before running, confirm the context exists in the loaded instance state:
bool valid = workflowState.ActivityExecutionContexts.Any(x => x.Id == instanceId);

Type guard

bool contextExists = workflowExecutionContext.ActivityExecutionContexts.Any(x => x.Id == handle.ActivityInstanceId);

Try / catch

try { await runner.RunAsync(instance, handle); } catch (Exception ex) { logger.LogError(ex, "Stale ActivityInstanceId {Id}; falling back to plain resume", instanceId); await runner.RunAsync(instance); }

Prevention

When it happens

Trigger: Calling WorkflowRunner.RunAsync (or ExecuteWorkflowAsync overloads) with an ActivityHandle whose ActivityInstanceId does not match any ActivityExecutionContext in the target workflow instance — e.g. the ID belongs to another instance, the instance was reloaded after the context completed, or the ID was stale after a state re-extraction.

Common situations: Bookmark resumption after the target activity already completed and its context was pruned; copying activity instance IDs between workflow instances; workflow state restored from persistence missing that execution context; retry logic resuming a finished activity.

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


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/259040b502b870a9. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs:151

            triggerActivityId,
            cancellationToken);

        var bookmarkId = options?.BookmarkId;
        var activityHandle = options?.ActivityHandle;

        if (!string.IsNullOrEmpty(bookmarkId))
        {
            var bookmark = workflowState.Bookmarks.FirstOrDefault(x => x.Id == bookmarkId);

            if (bookmark != null)
                workflowExecutionContext.ScheduleBookmark(bookmark);
        }
        else if (activityHandle != null)
        {
            if (!string.IsNullOrEmpty(activityHandle.ActivityInstanceId))
            {
                var activityExecutionContext = workflowExecutionContext.ActivityExecutionContexts.FirstOrDefault(x => x.Id == activityHandle.ActivityInstanceId)
                                               ?? throw new("No activity execution context found with the specified ID.");
                workflowExecutionContext.ScheduleActivityExecutionContext(activityExecutionContext);
            }
            else
            {
                var activity = workflowExecutionContext.FindActivity(activityHandle);
                if (activity != null) workflowExecutionContext.ScheduleActivity(activity);
            }
        }
        else if (workflowExecutionContext.Scheduler.HasAny)
        {
            // Do nothing. The scheduler already has activities to schedule.
        }
        else
        {
            // Check if there are any interrupted activities.
            var interruptedActivityExecutionContexts = workflowExecutionContext.ActivityExecutionContexts.Where(x => x.IsExecuting).ToList();

            if (interruptedActivityExecutionContexts.Count > 0)

View on GitHub (pinned to fe9217bdfa)