elsa-workflows/elsa-core · error · UniqueKeyConstraintViolationException
23505
23505
Error message
Unable to save data
What it means
The PostgreSQL DbExceptionTransformer handler converts EF Core DbUpdateException whose inner PostgresException has SqlState 23505 (unique_violation) into Elsa's UniqueKeyConstraintViolationException with message 'Unable to save data'. This normalizes provider-specific constraint errors into a typed exception the application/persistence layer can handle.
Solutions
- Catch UniqueKeyConstraintViolationException around save operations and implement idempotent upsert/skip logic.
- Check the violated key in the inner exception's Detail/ConstraintName to see which unique index fired.
- Deduplicate existing rows in the table if a new migration introduced a unique index over non-unique data.
- Use deterministic IDs or optimistic concurrency instead of relying on auto-generated values that can collide.
Example fix
// before
await dbContext.SaveChangesAsync();
// after
try { await dbContext.SaveChangesAsync(); }
catch (UniqueKeyConstraintViolationException ex)
{
// handle duplicate key, e.g. load existing and update instead of insert
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check for existence before insert where possible var exists = await dbSet.AnyAsync(x => x.Id == entity.Id, ct); if (exists) return await UpdateExistingAsync(entity, ct);
Try / catch
try
{
await dbContext.SaveChangesAsync(ct);
}
catch (UniqueKeyConstraintViolationException ex)
{
logger.LogInformation(ex.InnerException, "Duplicate key on save; applying idempotent handling");
// upsert or skip
} Prevention
- Use deterministic business keys and check-before-insert for idempotent operations.
- Guard concurrent workflow registration with locking or upsert semantics.
- Review unique indexes added by migrations against existing data before deploying.
- Catch the typed UniqueKeyConstraintViolationException rather than raw DbUpdateException.
When it happens
Trigger: Saving entities via EF Core SaveChanges when a UNIQUE constraint or unique index is violated in PostgreSQL (SqlState 23505) — e.g. inserting a duplicate workflow instance ID, duplicate definition version, or any key uniqueness conflict.
Common situations: Race condition where two concurrent workflow executions create the same record; re-importing/re-registering the same workflow definition; seeding data that already exists; unique index added by migrations conflicting with legacy duplicate rows.
Related errors
- Unable to save data
- Provider ' ' is not supported.
- Connection string not configured for
- The persisted external authentication value could not be…
- Storage unit ' ' is not declared in the persistence schema.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/35b94c2522e22cef.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Persistence.EFCore.PostgreSql/Handlers/DbExceptionTransformer.cs:18
using Elsa.Workflows.Exceptions;
using JetBrains.Annotations;
using Npgsql;
namespace Elsa.Persistence.EFCore.PostgreSql.Handlers;
/// <summary>
/// Transforms database exceptions encountered when using a postgreSQL database into more generic exceptions.
/// </summary>
[UsedImplicitly]
public class DbExceptionTransformer : IDbExceptionHandler
{
public Task HandleAsync(DbUpdateExceptionContext context)
{
var exception = context.Exception;
if (exception.InnerException is PostgresException { SqlState: "23505" })
throw new UniqueKeyConstraintViolationException("Unable to save data", exception);
throw new DataProcessingException("Unable to save data", exception);
}
}View on GitHub (pinned to fe9217bdfa)