elsa-workflows/elsa-core · error · Exception
Activity descriptor not found
Error message
Activity descriptor not found
What it means
A generic Exception thrown by EvaluateInputPropertyAsync when the activity registry lookup returns no descriptor for the activity's Type. It signals the activity type is unknown to the runtime, so its input descriptors cannot be resolved.
Solutions
- Install/register the activity's feature so its descriptor exists in the registry before evaluating inputs.
- Verify activity.Type matches a registered descriptor (spelling, namespace-derived type name).
- In tests, configure the workflow test host to include the activity types under test.
- Replace ad-hoc Exception handling: check the registry via FindAsync yourself to fail with a clearer message.
Example fix
// before
var descriptor = await registry.FindAsync(activity.Type) ?? throw new Exception("Activity descriptor not found");
// after
var descriptor = await registry.FindAsync(activity.Type);
if (descriptor is null)
throw new ActivityNotFoundException(activity.Type); // and ensure the activity is registered via its feature Defensive patterns
Strategy: type-guard
Validate before calling
var descriptor = await registryLookup.FindAsync(activity.Type);
if (descriptor is null) { /* skip evaluation or fail with clear message */ } Type guard
async ValueTask<bool> IsRegisteredAsync(IActivityRegistryLookupService lookup, IActivity activity) => await lookup.FindAsync(activity.Type) is not null;
Prevention
- Register activity types in the test host before evaluating inputs.
- Never evaluate inputs for activities outside installed features.
- Check registry contents when debugging unknown activity types.
When it happens
Trigger: Calling EvaluateInputPropertyAsync(activityName) on an ActivityExecutionContext whose Activity.Type is not registered in IActivityRegistryLookupService (FindAsync returns null).
Common situations: Evaluating input properties of custom/unregistered activities in unit tests without installing the corresponding feature; running a workflow whose activity types come from a missing module; type renamed without re-registering.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Activity type not found
- Output conversion failed during result validation
- No input with name could be found
- WorkflowExecutionContext not found. This value exists only…
- Activity not found.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/1510147590b99e41.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.InputEvaluation.cs:49
/// <summary>
/// Evaluates the specified input property of the activity.
/// </summary>
public async Task<T?> EvaluateInputPropertyAsync<TActivity, T>(Expression<Func<TActivity, Input<T>>> propertyExpression)
{
var inputName = propertyExpression.GetProperty()!.Name;
var input = await EvaluateInputPropertyAsync(context, inputName);
return input.ConvertTo<T>();
}
/// <summary>
/// Evaluates a specific input property of the activity.
/// </summary>
public async Task<object?> EvaluateInputPropertyAsync(string inputName)
{
var activity = context.Activity;
var activityRegistryLookup = context.GetRequiredService<IActivityRegistryLookupService>();
var activityDescriptor = await activityRegistryLookup.FindAsync(activity.Type) ?? throw new Exception("Activity descriptor not found");
var inputDescriptor = activityDescriptor.GetWrappedInputPropertyDescriptor(activity, inputName);
if (inputDescriptor == null)
throw new Exception($"No input with name {inputName} could be found");
return await EvaluateInputPropertyAsync(context, activityDescriptor, inputDescriptor);
}
/// <summary>
/// Evaluates the specified input and sets the result in the activity execution context's memory space.
/// </summary>
/// <param name="input">The input to evaluate.</param>
/// <typeparam name="T">The type of the input.</typeparam>
/// <returns>The evaluated value.</returns>
public async Task<T?> EvaluateAsync<T>(Input<T> input)
{
var evaluator = context.GetRequiredService<IExpressionEvaluator>();
var memoryBlockReference = input.MemoryBlockReference();View on GitHub (pinned to fe9217bdfa)