elsa-workflows/elsa-core · error · Exception

Syntax descriptor with expression type

Error message

Syntax descriptor with expression type {expressionType} not found in registry

What it means

SyntheticPropertiesWriter.WriteSyntheticInputProperties throws when an activity input's expression type is not registered in the IExpressionDescriptorRegistry. To serialize synthetic input properties it must find the descriptor (syntax) for the expression, and none exists. This means the expression provider that defines that syntax was never registered in the host.

Solutions

  1. Install/register the feature that provides the missing expression syntax (e.g. useJavaScript(), useCSharp(), useLiquid())
  2. Register a custom descriptor with IExpressionDescriptorRegistry for the expression type before serializing
  3. Remove or replace the input expression with a registered syntax in the workflow definition
  4. Check DI configuration so expression descriptors are registered before serialization occurs

Example fix

// before
services.AddElsa(elsa => elsa.AddActivitiesFrom<Startup>()); // no syntax registered
// after
services.AddElsa(elsa => elsa.AddActivitiesFrom<Startup>().UseJavaScript().UseLiquid());
Defensive patterns

Strategy: validation

Validate before calling

var expressionType = activity.Inputs.Select(i => i.Expression?.Type).Where(t => t != null).Distinct();
foreach (var t in expressionType)
    if (expressionDescriptorRegistry.Find(t) == null)
        throw new InvalidOperationException($"Expression syntax '{t}' is not registered. Install the matching feature package.");

Try / catch

try { var json = await workflowSerializer.SerializeAsync(workflow); }
catch (Exception ex) when (ex.Message.StartsWith("Syntax descriptor")) { logger.LogError(ex, "Register the missing expression syntax feature before serializing"); }

Prevention

When it happens

Trigger: An activity input (IInput with an Expression of type 'Foo') is serialized to a workflow definition model, but no expression descriptor named/typed 'Foo' was registered via AddSyntax<T> or the corresponding expression feature (e.g. JavaScript, CSharp, Liquid packages not installed).

Common situations: Serializing/saving a workflow that uses JavaScript expressions in a host without the Elsa JavaScript feature; a custom expression provider removed or conditionally registered; package version changes dropping a syntax provider from DI.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Serialization/Helpers/SyntheticPropertiesWriter.cs:51

            writer.WritePropertyName(propertyName);

            var input = (Input?)inputValue;

            if (input == null)
            {
                writer.WriteNullValue();
                continue;
            }

            var expression = input.Expression;
            var expressionType = expression?.Type;
            var inputType = input.Type;
            var memoryReferenceId = input.MemoryBlockReference().Id;
            var expressionDescriptor = expressionType != null ? expressionDescriptorRegistry.Find(expressionType) : null;

            if (expressionDescriptor == null)
                throw new Exception($"Syntax descriptor with expression type {expressionType} not found in registry");

            var inputModel = new
            {
                TypeName = inputType,
                Expression = expression,
                MemoryReference = new
                {
                    Id = memoryReferenceId
                }
            };

            JsonSerializer.Serialize(writer, inputModel, inputModel.GetType(), options);
        }
    }

    private void WriteSyntheticOutputProperties(Utf8JsonWriter writer, IActivity value, ActivityDescriptor activityDescriptor, JsonSerializerOptions options)
    {
        var syntheticOutputs = activityDescriptor.Outputs.Where(x => x.IsSynthetic).ToList();

View on GitHub (pinned to fe9217bdfa)