elsa-workflows/elsa-core · error · OutputConversionException

Output conversion failed during destination resolution

Error message

Output conversion failed during destination resolution

What it means

ActivityExecutionContext throws OutputConversionException with OutputConversionFailureStage.Resolution when resolving an output binding's destination returns null. The IOutputBindingDestinationResolver could not produce a destination for the given output, so the output value cannot be delivered. The exception names the converter, activity, output name, and memory block id for diagnosis.

Solutions

  1. Check the output's binding target (variable/output reference) exists in the definition and is in scope at the producing activity.
  2. Fix or implement the custom IOutputBindingDestinationResolver so it returns a valid destination or throws instead of null.
  3. Re-link the output in the designer to an existing variable so the destination resolves.
  4. Verify the resolvedOutputName and memory block id reported in the exception match an actually declared output.

Example fix

// before
class MyResolver : IOutputBindingDestinationResolver
{
    public MemoryBlockReference? Resolve(...) => null; // triggers OutputConversionException
}
// after
class MyResolver : IOutputBindingDestinationResolver
{
    public MemoryBlockReference? Resolve(...) =>
        variable != null ? variable.MemoryBlockReference() : throw new InvalidOperationException($"Destination for output '{outputName}' not found");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the output binding target exists before execution
var target = outputBinding.Variable ?? (object?)outputBinding.Output;
if (target == null)
    throw new InvalidOperationException($"Output '{outputName}' has no resolvable destination.");

Type guard

static bool HasResolvableDestination(IOutputBindingDestinationResolver resolver, ActivityExecutionContext context, Output output) => resolver.Resolve(context, output) != null;

Try / catch

try { await workflowRunner.RunAsync(workflow); }
catch (OutputConversionException ex) when (ex.FailureStage == OutputConversionFailureStage.Resolution)
{
    logger.LogError(ex, "Output '{Output}' on activity '{ActivityType}' has no resolvable destination", ex.OutputName, ex.ActivityType);
}

Prevention

When it happens

Trigger: Delivering an output value where the output has a binding whose destination resolver returns null — e.g. an output bound to a variable/output reference that cannot be resolved in the current scope, or a custom IOutputBindingDestinationResolver returning null.

Common situations: Output bound to a variable that was renamed or deleted; custom destination resolvers returning null instead of throwing descriptive errors; output name mismatches between activity and binding configuration.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.cs:800

            // Also store the value in the workflow execution transient activity output register.
            WorkflowExecutionContext.RecordActivityOutput(this, outputName, value);
            return;
        }

        var descriptor = ActivityDescriptor.Outputs.FirstOrDefault(x => x.PropertyInfo?.Name == outputName);
        descriptor ??= ActivityDescriptor.Outputs.FirstOrDefault(x => x.ValueGetter != null && ReferenceEquals(x.ValueGetter(Activity), output));
        var resolvedOutputName = descriptor?.Name ?? outputName ?? ActivityOutputRegister.DefaultOutputName;
        var sourceType = descriptor?.Type ?? GetOutputValueType(output.GetType()) ?? typeof(object);

        // The activity output register always retains the activity's native value.
        WorkflowExecutionContext.RecordActivityOutput(this, outputName, value);

        var destinationResolver = GetRequiredService<IOutputBindingDestinationResolver>();
        var destination = destinationResolver.Resolve(this, output);

        if (destination == null)
        {
            throw new OutputConversionException(
                output.Converter.Id,
                OutputConversionFailureStage.Resolution,
                Activity.Id,
                Activity.Type,
                resolvedOutputName,
                output.MemoryBlockReference().Id,
                sourceType,
                null);
        }

        if (value == null)
        {
            if (!destination.AllowsNull)
            {
                throw new OutputConversionException(
                    output.Converter.Id,
                    OutputConversionFailureStage.ResultValidation,
                    Activity.Id,

View on GitHub (pinned to fe9217bdfa)