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
- Register the missing type alias via the serialization type registry before deserializing (ISerializationTypeRegistry / AddType<...>("alias"))
- Ensure the module/package defining the type is referenced and installed in the consuming app
- Verify the JSON payload's type alias matches the alias used at serialization time (check for version skew)
- 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
- Register every serializable type's alias in both producing and consuming apps
- Pin Elsa package versions across services exchanging serialized workflows
- Test round-trip serialization in CI
- Avoid stripping assemblies with trimming without trimmer roots
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
- Workflow JSON type alias resolved to non-instantiable type
- Cannot deserialize to .
- Failed to deserialize
- The binding to activity type
- Expected number or string.
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)