elsa-workflows/elsa-core · error · ArgumentNullException

Value cannot be null. (Parameter 'type')

Error message

Value cannot be null. (Parameter 'type')

What it means

TypeExtensions.GetSimpleAssemblyQualifiedName is a null-forgiving extension that explicitly guards with ArgumentNullException. It computes a simplified assembly-qualified type name (no version info) and caches it; a null Type is never valid.

Solutions

  1. Ensure the Type is non-null before calling (check the result of Type.GetType)
  2. Throw or log early in the reflection helper that resolved the type
  3. Coalesce to a fallback type if the lookup can legitimately fail

Example fix

// before
var name = type.GetSimpleAssemblyQualifiedName();
// after
var name = type is null ? throw new InvalidOperationException("Type not resolved") : type.GetSimpleAssemblyQualifiedName();
Defensive patterns

Strategy: type-guard

Validate before calling

if (type is null) throw new InvalidOperationException("Type lookup failed before building AQN");

Type guard

static bool HasType(Type? t) => t is not null;

Try / catch

try { name = type.GetSimpleAssemblyQualifiedName(); } catch (ArgumentNullException) { name = null; }

Prevention

When it happens

Trigger: Passing a null Type reference to the extension, typically from reflection code that looked up a type by name and got null.

Common situations: Type.GetType returning null for misspelled or unloaded type names, then flowing into GetSimpleAssemblyQualifiedName.

Related errors


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

Appendix: source

Thrown at src/clients/Elsa.Api.Client/Extensions/TypeExtensions.cs:18

using System.Collections.Concurrent;

namespace Elsa.Api.Client.Extensions;

/// <summary>
/// Adds extension methods to <see cref="Type"/>.
/// </summary>
public static class TypeExtensions
{
    private static readonly ConcurrentDictionary<Type, string> SimpleAssemblyQualifiedTypeNameCache = new();

    /// <summary>
    /// Gets the assembly-qualified name of the type, without any version info etc.
    /// E.g. "System.String, System.Private.CoreLib"
    /// </summary>
    public static string GetSimpleAssemblyQualifiedName(this Type type)
    {
        if (type is null) throw new ArgumentNullException(nameof(type));
        return SimpleAssemblyQualifiedTypeNameCache.GetOrAdd(type, BuildSimplifiedName);
    }

    /// <summary>
    /// Returns the default value for the specified type.
    /// </summary>
    public static object? GetDefaultValue(this Type type) => type.IsClass ? null : Activator.CreateInstance(type);
    
    /// <summary>
    /// Returns the element type of the specified type representing an array or generic enumerable.
    /// </summary>
    public static Type GetEnumerableElementType(this Type type)
    {
        if (type.IsArray)
            return type.GetElementType()!;

        var elementType = FindIEnumerable(type);
        return elementType == null ? type : elementType.GetGenericArguments()[0];

View on GitHub (pinned to fe9217bdfa)