{"record":{"id":"5a198ed61cd2d377","repo":"elsa-workflows/elsa-core","slug":"output-conversion-failed-during-destination-resolution","errorCode":null,"errorMessage":"Output conversion failed during destination resolution","messagePattern":"Output conversion failed during destination resolution","errorType":"exception","errorClass":"OutputConversionException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.cs","lineNumber":800,"sourceCode":"            // Also store the value in the workflow execution transient activity output register.\n            WorkflowExecutionContext.RecordActivityOutput(this, outputName, value);\n            return;\n        }\n\n        var descriptor = ActivityDescriptor.Outputs.FirstOrDefault(x => x.PropertyInfo?.Name == outputName);\n        descriptor ??= ActivityDescriptor.Outputs.FirstOrDefault(x => x.ValueGetter != null && ReferenceEquals(x.ValueGetter(Activity), output));\n        var resolvedOutputName = descriptor?.Name ?? outputName ?? ActivityOutputRegister.DefaultOutputName;\n        var sourceType = descriptor?.Type ?? GetOutputValueType(output.GetType()) ?? typeof(object);\n\n        // The activity output register always retains the activity's native value.\n        WorkflowExecutionContext.RecordActivityOutput(this, outputName, value);\n\n        var destinationResolver = GetRequiredService<IOutputBindingDestinationResolver>();\n        var destination = destinationResolver.Resolve(this, output);\n\n        if (destination == null)\n        {\n            throw new OutputConversionException(\n                output.Converter.Id,\n                OutputConversionFailureStage.Resolution,\n                Activity.Id,\n                Activity.Type,\n                resolvedOutputName,\n                output.MemoryBlockReference().Id,\n                sourceType,\n                null);\n        }\n\n        if (value == null)\n        {\n            if (!destination.AllowsNull)\n            {\n                throw new OutputConversionException(\n                    output.Converter.Id,\n                    OutputConversionFailureStage.ResultValidation,\n                    Activity.Id,","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.cs#L782-L818","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the output's binding target (variable/output reference) exists in the definition and is in scope at the producing activity.","Fix or implement the custom IOutputBindingDestinationResolver so it returns a valid destination or throws instead of null.","Re-link the output in the designer to an existing variable so the destination resolves.","Verify the resolvedOutputName and memory block id reported in the exception match an actually declared output."],"exampleFix":"// before\nclass MyResolver : IOutputBindingDestinationResolver\n{\n    public MemoryBlockReference? Resolve(...) => null; // triggers OutputConversionException\n}\n// after\nclass MyResolver : IOutputBindingDestinationResolver\n{\n    public MemoryBlockReference? Resolve(...) =>\n        variable != null ? variable.MemoryBlockReference() : throw new InvalidOperationException($\"Destination for output '{outputName}' not found\");\n}","handlingStrategy":"try-catch","validationCode":"// verify the output binding target exists before execution\nvar target = outputBinding.Variable ?? (object?)outputBinding.Output;\nif (target == null)\n    throw new InvalidOperationException($\"Output '{outputName}' has no resolvable destination.\");","typeGuard":"static bool HasResolvableDestination(IOutputBindingDestinationResolver resolver, ActivityExecutionContext context, Output output) => resolver.Resolve(context, output) != null;","tryCatchPattern":"try { await workflowRunner.RunAsync(workflow); }\ncatch (OutputConversionException ex) when (ex.FailureStage == OutputConversionFailureStage.Resolution)\n{\n    logger.LogError(ex, \"Output '{Output}' on activity '{ActivityType}' has no resolvable destination\", ex.OutputName, ex.ActivityType);\n}","preventionTips":["Bind outputs only to variables/outputs declared in an enclosing scope.","Re-link outputs in the designer after renaming or deleting target variables.","Implement custom IOutputBindingDestinationResolvers to throw descriptive errors instead of returning null.","Validate output bindings when importing definitions from external sources."],"tags":["workflow","output","conversion","binding"],"backgroundTag":"invalid-argument-value","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}