elsa-workflows/elsa-core · error · InvalidOperationException
A configured default role no longer exists.
Error message
A configured default role no longer exists.
What it means
ResolveRoleIdsAsync validates the proposal's DefaultRoleIds against the role provider: every requested, non-empty, distinct role ID must be found by IRoleProvider.FindByIdsAsync. If any ID is missing (SetEquals fails), ResolveAsync throws, because creating a user with dangling role references would produce a broken identity. Roles are typically seeded by configuration or modules, so this usually means configuration drift or a missing seed.
Solutions
- Look up the actual role IDs in the Elsa role store and update the configured DefaultRoleIds to match exactly (IDs, not names).
- Create the missing roles (via the admin API, studio, or role seeding) so the configured IDs resolve.
- Verify the app connects to the database where those roles exist (tenant/environment mismatch).
- Remove the stale role ID from DefaultRoleIds if the role is intentionally retired.
Example fix
// before: appsettings "DefaultRoleIds": ["Administrator"] // name, not ID // after: use the real role ID from the Roles table "DefaultRoleIds": ["role-7f3a2b9c"], // or validate before provisioning: var roles = await roleProvider.FindByIdsAsync(proposal.DefaultRoleIds, ct); // ensure roles.Count == proposal.DefaultRoleIds.Distinct().Count()
Defensive patterns
Strategy: validation
Validate before calling
var requested = (proposal.DefaultRoleIds ?? []).Where(x => !string.IsNullOrWhiteSpace(x)).Distinct().ToList();
var found = (await roleProvider.FindByIdsAsync(requested, ct)).Select(r => r.Id).ToHashSet();
if (!found.SetEquals(requested))
{
var missing = requested.Except(found);
logger.LogError("Missing configured roles: {Missing}", string.Join(", ", missing));
proposal.DefaultRoleIds = requested.Where(found.Contains).ToList(); // or abort provisioning
} Type guard
async Task<bool> AllRolesExistAsync(IReadOnlyCollection<string> roleIds, CancellationToken ct)
{
var requested = roleIds.Where(x => !string.IsNullOrWhiteSpace(x)).Distinct().ToList();
if (requested.Count == 0) return true;
var found = (await roleProvider.FindByIdsAsync(requested, ct)).Select(r => r.Id).ToHashSet();
return found.SetEquals(requested);
} Try / catch
try
{
var (user, created) = await provisioning.ResolveAsync(request, ct: ct);
}
catch (InvalidOperationException ex) when (ex.Message == "A configured default role no longer exists.")
{
logger.LogError(ex, "Configured DefaultRoleIds reference missing roles; check role seeding/config");
throw; // do not create a user with missing roles
} Prevention
- Store role IDs, not role names, in DefaultRoleIds configuration and verify them on startup.
- Run role seeding on every environment and after database recreation.
- Guard role deletion against references from provisioning configuration.
- Log which specific role IDs are missing to speed up diagnosis.
When it happens
Trigger: ProvisioningRequest.Proposal.DefaultRoleIds contains a role ID that does not exist in the role store — e.g. roles configured by ID in appsettings that were never created, a role deleted by an admin, roles from another tenant/database not present in the current role provider, or IDs containing stale values after re-seeding.
Common situations: Configuring DefaultRoleIds with role names instead of role IDs; environment drift (staging config copied to production where roles have different IDs); roles deleted during cleanup; database recreated without running role seeders.
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
- A role with ID ' ' already exists.
- Register with configured before calling , or call with a…
- The console log provider registration is invalid.
- OpenTelemetry gRPC ingestion is enabled, but no gRPC…
- Capacity must be greater than zero.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/350fceedb3a2742a.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.ExternalAuthentication/Services/ExternalIdentityUserProvisioningService.cs:121
? await userStore.FindAsync(new()
{ Id = user.Id }, cancellationToken) is not null
: await userProvider.FindAsync(new()
{ Id = user.Id }, cancellationToken) is not null;
private static string NormalizeUserNamePrefix(string prefix)
{
var normalized = new string((prefix ?? string.Empty).Trim().Where(character => char.IsAsciiLetterOrDigit(character) || character is '-' or '_').ToArray());
return string.IsNullOrEmpty(normalized) ? "external" : normalized;
}
private async ValueTask<IReadOnlyCollection<string>> ResolveRoleIdsAsync(IReadOnlyCollection<string>? roleIds, CancellationToken cancellationToken)
{
var requested = (roleIds ?? []).Where(x => !string.IsNullOrWhiteSpace(x)).Distinct(StringComparer.Ordinal).ToArray();
if (requested.Length == 0)
return [];
var found = (await roleProvider.FindByIdsAsync(requested, cancellationToken)).Select(x => x.Id).ToHashSet(StringComparer.Ordinal);
if (!found.SetEquals(requested))
throw new InvalidOperationException("A configured default role no longer exists.");
return requested;
}
}
View on GitHub (pinned to fe9217bdfa)