elsa-workflows/elsa-core · error · InvalidOperationException

WorkflowExecutionContext not found. This value exists only…

Error message

WorkflowExecutionContext not found. This value exists only on activity execution contexts.

What it means

An InvalidOperationException thrown by GetWorkflowExecutionContext when the ExpressionExecutionContext's TransientProperties dictionary does not contain the WorkflowExecutionContext key. WorkflowExecutionContext is only attached to transient properties when an expression is evaluated within an activity execution; standalone evaluations lack it.

Solutions

  1. Only call this inside code that runs during activity execution, where TransientProperties is populated.
  2. Use TryGetValue on context.TransientProperties with the WorkflowExecutionContextKey to test presence first.
  3. Pass the WorkflowExecutionContext explicitly to your evaluation code instead of pulling it from the expression context.
  4. In tests, populate TransientProperties[WorkflowExecutionContextKey] with a real or stubbed context.

Example fix

// before
var workflowExecutionContext = context.GetWorkflowExecutionContext(); // throws outside activity execution

// after
if (context.TransientProperties.TryGetValue(WorkflowExecutionContextKey, out var value) && value is WorkflowExecutionContext wfCtx)
{
    // use wfCtx
}
Defensive patterns

Strategy: type-guard

Validate before calling

var hasWorkflowContext = expressionContext.TransientProperties.ContainsKey(WorkflowExecutionContextKey);

Type guard

bool TryGetWorkflowExecutionContext(ExpressionExecutionContext ctx, out WorkflowExecutionContext? wfCtx)
    => ctx.TransientProperties.TryGetValue(WorkflowExecutionContextKey, out var v) && (wfCtx = v as WorkflowExecutionContext) is not null;

Try / catch

catch (InvalidOperationException ex) when (ex.Message.StartsWith("WorkflowExecutionContext not found"))
{
    // fall back to explicit context passing
}

Prevention

When it happens

Trigger: Calling GetWorkflowExecutionContext() on an ExpressionExecutionContext created outside activity execution - e.g., evaluating an expression at design time, in a workflow-level (not activity-level) context, or via a custom evaluator that did not populate TransientProperties.

Common situations: Custom expression syntax/plugins that evaluate expressions without the normal activity pipeline; designer-time evaluation/preview; background jobs evaluating stored expressions without a running workflow; unit tests constructing bare ExpressionExecutionContexts.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs:82

            [InputKey] = input
        };

    /// <param name="context">The context to start searching from.</param>
    extension(ExpressionExecutionContext context)
    {
        /// <summary>
        /// Returns the <see cref="Workflow"/> of the specified <see cref="ExpressionExecutionContext"/>
        /// </summary>
        public bool TryGetWorkflowExecutionContext(out WorkflowExecutionContext workflowExecutionContext) => context.TransientProperties.TryGetValue(WorkflowExecutionContextKey, out workflowExecutionContext!);

        /// <summary>
        /// Returns the <see cref="WorkflowExecutionContext"/> of the specified <see cref="ExpressionExecutionContext"/>
        /// </summary>
        public WorkflowExecutionContext GetWorkflowExecutionContext()
        {
            return context.TransientProperties.TryGetValue(WorkflowExecutionContextKey, out var value)
                ? (WorkflowExecutionContext)value
                : throw new InvalidOperationException("WorkflowExecutionContext not found. This value exists only on activity execution contexts.");
        }

        /// <summary>
        /// Returns the <see cref="ActivityExecutionContext"/> of the specified <see cref="ExpressionExecutionContext"/>
        /// </summary>
        public ActivityExecutionContext GetActivityExecutionContext()
        {
            return context.TransientProperties.TryGetValue(ActivityExecutionContextKey, out var value)
                ? (ActivityExecutionContext)value
                : throw new InvalidOperationException("ActivityExecutionContext not found. This value exists only on activity execution contexts.");
        }

        /// <summary>
        /// Returns the <see cref="ActivityExecutionContext"/> of the specified <see cref="ExpressionExecutionContext"/>
        /// </summary>
        public bool TryGetActivityExecutionContext(out ActivityExecutionContext activityExecutionContext) => context.TransientProperties.TryGetValue(ActivityExecutionContextKey, out activityExecutionContext!);

        /// <summary>

View on GitHub (pinned to fe9217bdfa)