elsa-workflows/elsa-core · error · JsonException

Unknown serialization type alias

Error message

Unknown serialization type alias '{typeAlias}'. Only registered aliases and supported compound aliases can be deserialized.

What it means

ResolveType maps a serialized type alias back to a CLR Type during JSON deserialization. When the alias is not registered in the ISerializationTypeRegistry and does not match a supported compound alias, Elsa cannot safely materialize the type and throws a JsonException so the deserialization fails loudly instead of loading an unknown type.

Solutions

  1. Register the missing type alias via the serialization type registry before deserializing (ISerializationTypeRegistry / AddType<...>("alias"))
  2. Ensure the module/package defining the type is referenced and installed in the consuming app
  3. Verify the JSON payload's type alias matches the alias used at serialization time (check for version skew)
  4. If using trimming/PublishSingleFile, add the type to the TrimmerRootAssembly or disable trimming for the assembly

Example fix

// before: deserializing payload with alias "my-custom-activity" that is unregistered
var model = JsonSerializer.Deserialize<WorkflowEnvelope>(json);
// after: register the alias first
services.AddSerialization(options => options.AddType<MyCustomActivity>("my-custom-activity"));
var model = JsonSerializer.Deserialize<WorkflowEnvelope>(json);
Defensive patterns

Strategy: try-catch

Validate before calling

var alias = ExtractAlias(json);
var known = alias is null || serializationTypeRegistry.TryGetType(alias, out _);
if (!known) throw new InvalidOperationException($"Alias '{alias}' is not registered before deserialize.");

Type guard

bool IsRegisteredAlias(string alias) => !string.IsNullOrWhiteSpace(alias) && serializationTypeRegistry.TryGetType(alias, out _);

Try / catch

try { return JsonSerializer.Deserialize<T>(json); }
catch (JsonException ex) when (ex.Message.Contains("Unknown serialization type alias"))
{ logger.LogWarning(ex, "Unregistered type alias in payload"); return null; }

Prevention

When it happens

Trigger: Deserializing JSON whose $type / type alias field contains an alias that was never registered, or whose serialization producer registered types that the consuming application did not (e.g. missing module registration, trimmed/published app missing a type, or payload from a different Elsa version).

Common situations: Sharing workflow instance/checkpoint JSON between apps with different registered activities; renaming or removing an activity type; R2R/trimming stripping types; deserializing a payload produced by a newer Elsa version that registered extra aliases.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Common/Serialization/SerializationTypeResolver.cs:65

    {
        [typeof(IEnumerable)] = typeof(List<object>),
        [typeof(ICollection)] = typeof(List<object>),
        [typeof(IList)] = typeof(List<object>),
        [typeof(IDictionary)] = typeof(Dictionary<string, object>)
    };

    /// <summary>
    /// Resolves the specified serialization type alias.
    /// </summary>
    public static Type ResolveType(ISerializationTypeRegistry serializationTypeRegistry, string? typeAlias)
    {
        if (string.IsNullOrWhiteSpace(typeAlias))
            throw new JsonException("The serialization type alias is missing.");

        if (TryResolveType(serializationTypeRegistry, typeAlias, out var type))
            return type;

        throw new JsonException(
            $"Unknown serialization type alias '{typeAlias}'. Only registered aliases and supported compound aliases can be deserialized.");
    }

    /// <summary>
    /// Attempts to resolve the specified serialization type alias.
    /// </summary>
    public static bool TryResolveType(ISerializationTypeRegistry serializationTypeRegistry, string typeAlias, out Type type)
    {
        IReadOnlyList<Type>? registeredTypes = null;
        return TryResolveType(serializationTypeRegistry, typeAlias, ref registeredTypes, out type);
    }

    private static bool TryResolveType(ISerializationTypeRegistry serializationTypeRegistry, string typeAlias, ref IReadOnlyList<Type>? registeredTypes, out Type type)
    {
        if (serializationTypeRegistry.TryGetType(typeAlias, out var registeredType))
        {
            type = registeredType;
            return true;

View on GitHub (pinned to fe9217bdfa)