elsa-workflows/elsa-core · error · InvalidOperationException
Activity ' ' not found in registry
Error message
Activity '{actInv.ActivityName}' not found in registry What it means
When compiling an activity invocation, ElsaScriptCompiler looks the activity up by name in the activity registry (activityRegistryLookupService.FindAsync). If no descriptor matches the invoked name, it throws InvalidOperationException stating the activity was not found in the registry. The script is calling an activity Elsa does not know about in the current host.
Solutions
- Correct the activity name in the script to match the registry (check casing).
- Register the module/feature that provides the activity with the workflow host (e.g. UseHttp(), UseTimers()).
- Verify with the Activity Registry what names are available; print candidate names for the invoked type.
- Catch InvalidOperationException from the compiler and report the unknown activity to the script author.
Example fix
// before
await compile("sendMail(to: x)"); // activity not installed
// after
services.AddElsa(elsa => elsa.UseSendMail()); // register the module first
await compile("sendMail(to: x)"); Defensive patterns
Strategy: validation
Validate before calling
const known = await activityRegistryClient.listNames(); const missing = script.activityNames.filter(n => !known.includes(n)); if (missing.length) throw new Error('Unknown activities: ' + missing.join(', ')); Type guard
function isKnownActivity(name, registry) { return registry.some(d => d.name === name); } Try / catch
try { await compileScript(script); } catch (InvalidOperationException ex) when (ex.Message.Contains("not found in registry")) { suggestMatchingRegistryNames(ex); } Prevention
- Register all feature packages providing the activities your scripts use.
- Validate activity names against the registry before compiling.
- Use editor autocomplete backed by the Activity Registry to prevent typos.
- Keep script authoring environments' installed modules in sync with production.
When it happens
Trigger: Calling an activity by name in an ElsaScript while the registry (populated from installed feature packages) has no descriptor whose Name equals the invoked name — e.g. name typos, casing differences, or the module providing the activity not registered with the host.
Common situations: Misspelled activity name in the script, missing Elsa feature package/UseX registration on the server, activity registered only under a different name/type, or the compiler built with a narrower registry lookup scope.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Workflow definition with ID
- AlterationFaultCodes.PlanNotFound
- The binding names activity type
- Workflow definition ' ' does not exist, so its BPMN…
- Statement type is not supported
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/0efb78bb34f38e65.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Dsl.ElsaScript/Compiler/ElsaScriptCompiler.cs:187
{
// Try to find the activity type by name - try several strategies
var activityDescriptor = await activityRegistryLookupService.FindAsync(actInv.ActivityName);
// If not found, try with "Elsa." prefix
if (activityDescriptor == null)
{
activityDescriptor = await activityRegistryLookupService.FindAsync($"Elsa.{actInv.ActivityName}");
}
// If still not found, search by descriptor name
if (activityDescriptor == null)
{
activityDescriptor = await activityRegistryLookupService.FindAsync(d => d.Name == actInv.ActivityName);
}
if (activityDescriptor == null)
{
throw new InvalidOperationException($"Activity '{actInv.ActivityName}' not found in registry");
}
var activityType = activityDescriptor.ClrType;
// Separate named and positional arguments
var namedArgs = actInv.Arguments.Where(a => a.Name != null).ToList();
var positionalArgs = actInv.Arguments.Where(a => a.Name == null).ToList();
IActivity activity;
// If we have positional arguments, try to find a matching constructor
if (positionalArgs.Any())
{
activity = InstantiateActivityUsingConstructor(activityType, positionalArgs);
}
else
{
// No positional arguments, use default constructorView on GitHub (pinned to fe9217bdfa)