elsa-workflows/elsa-core · error · JsonException
Failed to extract activity type property
Error message
Failed to extract activity type property
What it means
GetActivityDetails reads the required 'type' property from a JSON activity object to determine which activity to instantiate. If the JSON object has no 'type' property, this JsonException is thrown. Every serialized Elsa activity must carry a 'type' discriminator.
Solutions
- Add the required "type" property with the activity's registered type name (e.g. "type": "HttpEndpoint").
- If versioned, include the activity version field as produced by a normal Elsa export.
- Re-export the workflow from Elsa Studio/Designer to get a canonical payload instead of hand-writing JSON.
Example fix
// before
{ "id": "step-1", "properties": {} }
// after
{ "type": "WriteLine", "id": "step-1", "properties": {} } Defensive patterns
Strategy: validation
Validate before calling
using var doc = JsonDocument.Parse(json);
if (doc.RootElement.ValueKind != JsonValueKind.Object || !doc.RootElement.TryGetProperty("type", out _))
throw new InvalidOperationException("Activity JSON must contain a 'type' property"); Type guard
static bool HasActivityType(JsonElement e) => e.ValueKind == JsonValueKind.Object && e.TryGetProperty("type", out var t) && t.ValueKind == JsonValueKind.String && !string.IsNullOrEmpty(t.GetString()); Try / catch
try { var activity = JsonSerializer.Deserialize<IActivity>(json); } catch (JsonException ex) when (ex.Message.Contains("Failed to extract activity type property")) { log.LogError(ex, "Activity JSON missing 'type' discriminator"); } Prevention
- Always include "type" in hand-authored activity JSON
- Prefer re-exporting workflows from Elsa Studio over manual JSON editing
- Watch out for middleware/serializers configured with IgnoreNullValues or property filters that strip discriminators
When it happens
Trigger: Deserializing an activity JSON object that lacks a 'type' member — e.g. {"id":"x"} or JSON produced by tools that strip the discriminator — encountered in ActivityJsonConverter.GetActivityDetails (src/modules/Elsa.Workflows.Core/Serialization/Converters/ActivityJsonConverter.cs:108).
Common situations: Manually authoring composite or custom activity JSON without 'type'; third-party serializers stripping unknown properties; transforming workflow JSON with jq/JSON tools that drop fields.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Runtime entity definition document
- Runtime entity instance document
- Failed to parse JsonDocument
- Unknown token
- Expected start of object.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/607fd88853b33a7d.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Core/Serialization/Converters/ActivityJsonConverter.cs:108
logger.LogWarning("An exception was thrown while constructing activity with id '{activityId}': {Message}", result.Activity.Id, exception.Message);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, IActivity value, JsonSerializerOptions options)
{
var clonedOptions = GetClonedWriterOptions(options);
var activityDescriptor = activityRegistry.Find(value.Type, value.Version);
// Give the activity descriptor a chance to customize the serializer options.
clonedOptions = activityDescriptor?.ConfigureSerializerOptions?.Invoke(clonedOptions) ?? clonedOptions;
activityWriter.WriteActivity(writer, value, clonedOptions);
}
private string GetActivityDetails(JsonElement activityRoot, out int activityTypeVersion, out ActivityDescriptor? activityDescriptor)
{
if (!activityRoot.TryGetProperty("type", out var activityTypeNameElement))
throw new JsonException("Failed to extract activity type property");
var activityTypeName = activityTypeNameElement.GetString()!;
activityDescriptor = null;
activityTypeVersion = 0;
// First, we check whether the activity type name is a 'well-known' activity; not a workflow-as-activity
// If the activity type version is specified, use that to find the activity descriptor.
if (activityRoot.TryGetProperty("version", out var activityVersionElement))
{
activityTypeVersion = activityVersionElement.GetInt32();
activityDescriptor = activityRegistry.Find(activityTypeName, activityTypeVersion);
}
// If a version is not specified, or activity with specified version is not found: use the latest version of the activity descriptor.
if (activityDescriptor == null)
{
activityDescriptor = activityRegistry.Find(activityTypeName);View on GitHub (pinned to fe9217bdfa)