elsa-workflows/elsa-core · error · InvalidOperationException
A already exists with ' ' in tenant ' '.
Error message
A {entityType} already exists with {keyName} '{key}' in tenant '{tenantId}'. What it means
MemoryIdentityUniqueness.EnsureAvailable checks an in-memory entity set for another entity of the same type in the same tenant with an equal key (by keySelector) but a different Id. If such a candidate exists it throws InvalidOperationException, since creating/updating the entity would violate the uniqueness constraint (e.g. a duplicate user name or application name within a tenant).
Solutions
- Before creating/renaming, query the store for an entity with the same key in the tenant and reuse or reject it in application code.
- Make startup seeding idempotent: look up the entity by key first and update it rather than adding a new one.
- If the key is genuinely distinct, verify the tenant ID is correct - the conflict is scoped per tenant, so a wrong tenant can surface an apparent collision.
- Use a real persistence provider with a unique index if stronger guarantees than the in-memory store are needed.
Example fix
// before
await userManager.CreateAsync(new User { Name = "admin", TenantId = tenantId });
// after
var existing = await userManager.FindByNameAsync("admin", tenantId);
if (existing is null)
await userManager.CreateAsync(new User { Name = "admin", TenantId = tenantId }); Defensive patterns
Strategy: validation
Validate before calling
var duplicate = (await userRegistry.ListAsync(tenantId)).Any(u => u.Name == candidateName);
if (duplicate) throw new InvalidOperationException($"A user named '{candidateName}' already exists in tenant '{tenantId}'."); Try / catch
try { await EnsureAvailableAndCreateAsync(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already exists with"))
{
// handle duplicate: reuse existing entity or surface validation message
} Prevention
- Make all identity seeding idempotent (lookup-before-insert).
- Use unique, generated names in tests/parallel seeds to avoid shared in-memory store collisions.
- Validate name uniqueness in the UI/API layer before invoking identity services.
When it happens
Trigger: Calling identity APIs that create or rename users/applications/roles via the in-memory identity store when the requested key (e.g. user name) already exists on a different entity within the same tenant. The generic message interpolates the entity type name, key name, key value, and tenant ID.
Common situations: Seeding identity data twice on application startup without idempotency checks, registering two users with the same name in one tenant, renaming an entity to a name already taken by another entity, or running multiple seeds concurrently against the shared in-memory store in tests.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- A label already exists with normalized name
- A role with ID ' ' already exists.
- Cannot overwrite an AI conversation that belongs to another…
- Cannot overwrite an AI conversation that belongs to another…
- A conversation ID is required. (Parameter 'conversation')
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/ecceda7c6241672b.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Identity/Services/MemoryIdentityUniqueness.cs:31
/// Throws when another Id in the same tenant already owns <paramref name="keySelector"/>.
/// Same-Id upserts are allowed so a row can rename itself.
/// </summary>
public static void EnsureAvailable<T>(
MemoryStore<T> store,
T entity,
Func<T, string?> keySelector,
string keyName)
where T : Entity
{
var key = keySelector(entity);
var existing = store.Find(candidate =>
candidate.TenantId == entity.TenantId
&& candidate.Id != entity.Id
&& keySelector(candidate) == key);
if (existing is not null)
{
throw new InvalidOperationException(
$"A {typeof(T).Name.ToLowerInvariant()} already exists with {keyName} '{key}' in tenant '{entity.TenantId}'.");
}
}
}
View on GitHub (pinned to fe9217bdfa)