elsa-workflows/elsa-core · error · InvalidCastException

Unable to convert value of type

Error message

Unable to convert value of type '{value.GetType().FullName}' to type '{typeof(T).FullName}'.

What it means

GetActivityOutput<T> attempts conversion (including System.Convert for numeric widening) and wraps any failure in InvalidCastException with both source and target type names. It preserves the inner exception as the cause. This happens after the null check, i.e. a value existed but could not be converted.

Solutions

  1. Match T to the actual output type declared by the activity (check the activity's Output property type)
  2. Inspect the inner exception to see the exact conversion failure
  3. Convert explicitly in user code (e.g. DateTime.Parse) before/instead of the generic cast
  4. Use object as T and cast manually with checks

Example fix

// before
var ts = result.GetActivityOutput<string>("Timer");
// after
var ts = result.GetActivityOutput<DateTimeOffset>("Timer").ToString("O");
Defensive patterns

Strategy: try-catch

Validate before calling

var raw = result.GetActivityOutput<object?>(id); if (raw is T typed) { /* use typed */ }

Type guard

bool TryGetOutput<T>(IWorkflowExecutionResult r, string id, out T? value) { var raw = r.GetActivityOutput<object?>(id); if (raw is T t) { value = t; return true; } value = default; return false; }

Try / catch

try { value = result.GetActivityOutput<T>(id); } catch (InvalidCastException ex) { logger.LogError(ex, "Output {Id} not convertible to {Type}", id, typeof(T)); }

Prevention

When it happens

Trigger: Retrieving an output as T where the stored value's runtime type has no conversion to T, e.g. GetActivityOutput<string>("Timer") when the output is a DateTimeOffset, or incompatible numeric/object casts that Convert.ChangeType rejects.

Common situations: Assuming the wrong output type after changing an activity; deserialized output arriving as JsonElement/string while code expects a typed object; culture-dependent parse failures inside Convert.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Extensions/WorkflowExecutionResultExtensions.cs:39

            return default(T) is null ? default! : throw new InvalidCastException($"Cannot convert null to non-nullable type {typeof(T).FullName}.");
        }

        // Try to convert using System.Convert when possible (handles numeric casts like Double -> Int32).
        try
        {
            var targetType = typeof(T);

            // Unwrap nullable<T> to its underlying type for conversion.
            var underlyingType = Nullable.GetUnderlyingType(targetType) ?? targetType;

            var converted = Convert.ChangeType(value, underlyingType, System.Globalization.CultureInfo.InvariantCulture);

            // If T is nullable and we converted to the underlying type, just cast.
            return (T)converted!;
        }
        catch (Exception ex)
        {
            throw new InvalidCastException($"Unable to convert value of type '{value.GetType().FullName}' to type '{typeof(T).FullName}'.", ex);
        }
    }
}

View on GitHub (pinned to fe9217bdfa)