elsa-workflows/elsa-core · error · InvalidOperationException
The requested Elsa user does not exist.
Error message
The requested Elsa user does not exist.
What it means
ExternalIdentityUserProvisioningService.ResolveAsync throws this when the caller supplies request.ExistingUserId but no Elsa user with that ID can be found via IUserProvider.FindAsync. The service only links an external identity to an explicitly chosen existing user, and it refuses to silently create one when the given ID is stale or wrong. It indicates a reference to a deleted or never-existing Elsa user.
Solutions
- Verify the ExistingUserId value matches a real row in the Elsa user store (check via the admin API or database query on Users).
- Remove or regenerate the external identity link so a fresh user is created from the Proposal instead of linking to the stale ID.
- Confirm the application connects to the correct database/tenant where the user actually exists.
- Re-provision the user: clear the stored external identity mapping and log in again so ResolveAsync creates a new user.
Example fix
// before: stale stored link
request.ExistingUserId = storedLinkId; // deleted user
// after: validate before linking
var user = await userProvider.FindAsync(new() { Id = storedLinkId }, ct);
request.ExistingUserId = user is null ? null : storedLinkId; // fall back to proposal-based creation Defensive patterns
Strategy: validation
Validate before calling
if (!string.IsNullOrWhiteSpace(request.ExistingUserId))
{
var user = await userProvider.FindAsync(new() { Id = request.ExistingUserId }, ct);
if (user is null)
{
// stale link — drop it so a fresh user is provisioned from the proposal
request.ExistingUserId = null;
}
} Type guard
bool IsValidExistingUserId(ProvisioningRequest r) => string.IsNullOrWhiteSpace(r.ExistingUserId) || !string.IsNullOrWhiteSpace(r.ExistingUserId); // existence must be checked against the store asynchronously
Try / catch
try
{
var (user, created) = await provisioning.ResolveAsync(request, ct: ct);
}
catch (InvalidOperationException ex) when (ex.Message == "The requested Elsa user does not exist.")
{
request.ExistingUserId = null; // re-resolve via proposal path
var (user, created) = await provisioning.ResolveAsync(request, ct: ct);
} Prevention
- Validate the stored external identity link against the user store at startup or before each login.
- Cascade-delete external identity links when Elsa users are deleted.
- Never hardcode or copy user IDs across environments.
When it happens
Trigger: Calling ResolveAsync (directly or via an external-identity provisioner such as an OIDC/legacy login flow) with a ProvisioningRequest whose ExistingUserId is set to an ID that does not exist in the Elsa user store — e.g. the user was deleted in Elsa while still referenced externally, the ID was truncated/mangled, or the wrong store/tenant database is queried.
Common situations: Re-running provisioning after an admin deleted Elsa users; pointing the app at a fresh/empty database while still carrying old external identity links; copying user IDs between environments; case- or whitespace-corrupted IDs in configuration.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- A user creation proposal is required for an unlinked…
- The requested Elsa user is outside the target tenant.
- A unique Elsa user name could not be reserved for the…
- This external identity provisioner does not support atomic…
- The external authentication session user no longer exists.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/31d2517438053ece.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.ExternalAuthentication/Services/ExternalIdentityUserProvisioningService.cs:33
IUserProvider userProvider,
IRoleProvider roleProvider,
IIdentityGenerator identityGenerator)
{
private const int MaximumUserNameAttempts = 10;
/// <summary>
/// Resolves an explicitly selected user or creates a credential-less user from the supplied proposal.
/// </summary>
public async ValueTask<(User User, bool WasCreated)> ResolveAsync(
ProvisioningRequest request,
Func<string, bool>? tryReserveUserName = null,
CancellationToken cancellationToken = default)
{
if (!string.IsNullOrWhiteSpace(request.ExistingUserId))
{
var existingUser = await userProvider.FindAsync(new()
{ Id = request.ExistingUserId }, cancellationToken)
?? throw new InvalidOperationException("The requested Elsa user does not exist.");
if (!string.Equals(existingUser.TenantId, request.TenantId, StringComparison.Ordinal))
throw new InvalidOperationException("The requested Elsa user is outside the target tenant.");
return (existingUser, false);
}
var proposal = request.Proposal ?? throw new InvalidOperationException("A user creation proposal is required for an unlinked external identity.");
var roleIds = await ResolveRoleIdsAsync(proposal.DefaultRoleIds, cancellationToken);
var prefix = NormalizeUserNamePrefix(proposal.UserNamePrefix);
for (var attempt = 0; attempt < MaximumUserNameAttempts; attempt++)
{
var name = $"{prefix}-{identityGenerator.GenerateId()}";
if (tryReserveUserName is not null && !tryReserveUserName(name))
continue;
if (await userProvider.FindAsync(new()
{ Name = name }, cancellationToken) is not null)
continue;
View on GitHub (pinned to fe9217bdfa)