elsa-workflows/elsa-core · error · Exception

Cannot set result on activity

Error message

Cannot set result on activity {context.Activity.Id} because it does not implement {nameof(IActivityWithResult)}.

What it means

SetResult is an extension on ActivityExecutionContext that stores an activity's result via the strongly-typed Result property defined on IActivityWithResult. If the underlying activity does not implement that interface there is no Result memory register to write to, so the extension throws this exception instead of silently dropping the value.

Solutions

  1. Make the custom activity implement IActivityWithResult (or inherit from Activity<object>/Activity<T> which exposes Result) so SetResult has a register to write.
  2. Replace SetResult with context.Set(activity, "Result", value) on a memory register the activity actually declares, e.g. an Output.
  3. Have the caller only invoke SetResult after checking `activity is IActivityWithResult` and handle the else branch differently.
  4. Use context.Set(Outcome/Output) APIs appropriate to the activity's declared ports instead of the result shortcut.

Example fix

// before
context.SetResult(result); // throws for activities without IActivityWithResult
// after
if (context.Activity is IActivityWithResult withResult)
    context.Set(withResult.Result, result, "Result");
else
    context.Set(new Output<object>(), result); // or make the activity implement IActivityWithResult
Defensive patterns

Strategy: type-guard

Validate before calling

var activity = context.Activity as IActivityWithResult;
if (activity == null)
    throw new InvalidOperationException($"Activity {context.Activity.Id} must implement IActivityWithResult before SetResult");

Type guard

if (context.Activity is not IActivityWithResult activityWithResult) return;

Try / catch

try { context.SetResult(value); } catch (Exception ex) { logger.LogError(ex, "SetResult failed on activity {ActivityId}", context.Activity.Id); }

Prevention

When it happens

Trigger: Calling context.SetResult(value) (an ActivityExecutionContext extension) when context.Activity is a plain activity type that does not implement Elsa.Workflows.IActivityWithResult.

Common situations: Generic helper code that sets results on arbitrary activities; activities authored without IActivityResult/IActivityWithResult but whose output is expected downstream; refactors that removed the interface from a custom activity while callers still set results.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs:72

        /// <summary>
        /// Gets a value from the input provided via <see cref="WorkflowExecutionContext"/>. If a value was found, an attempt is made to convert it into the specified type <code>T</code>.
        /// </summary>
        public T GetWorkflowInput<T>(string key, JsonSerializerOptions? serializerOptions = null)
        {
            var wellKnownTypeRegistry = context.GetRequiredService<IWellKnownTypeRegistry>();
            return context.WorkflowInput[key].ConvertTo<T>(new(serializerOptions, wellKnownTypeRegistry))!;
        }

        /// <summary>
        /// Sets the Result property of the specified activity.
        /// </summary>
        /// being extended.
        /// <param name="value">The value to set.</param>
        /// <exception cref="Exception">Thrown when the specified activity does not implement <see cref="IActivityWithResult"/>.</exception>
        public void SetResult(object? value)
        {
            var activity = context.Activity as IActivityWithResult ?? throw new($"Cannot set result on activity {context.Activity.Id} because it does not implement {nameof(IActivityWithResult)}.");
            context.Set(activity.Result, value, "Result");
        }

        /// <summary>
        /// Returns true if this activity is triggered for the first time and not being resumed.
        /// </summary>
        public bool IsTriggerOfWorkflow() => context.WorkflowExecutionContext.TriggerActivityId == context.Activity.Id;

        /// <summary>
        /// Creates a workflow variable by name and optionally sets the value.
        /// </summary>
        /// <param name="name">The name of the variable.</param>
        /// <param name="value">The value of the variable.</param>
        /// <param name="storageDriverType">The type of storage driver to use for the variable.</param>
        /// <param name="configure">A callback to configure the memory block.</param>
        /// <returns>The created <see cref="Variable"/>.</returns>
        public Variable CreateVariable(string name, object? value, Type? storageDriverType = null, Action<MemoryBlock>? configure = null)
        {

View on GitHub (pinned to fe9217bdfa)