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

  1. Correct the activity name in the script to match the registry (check casing).
  2. Register the module/feature that provides the activity with the workflow host (e.g. UseHttp(), UseTimers()).
  3. Verify with the Activity Registry what names are available; print candidate names for the invoked type.
  4. 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

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


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 constructor

View on GitHub (pinned to fe9217bdfa)