elsa-workflows/elsa-core · critical · InvalidOperationException
Connection string not configured for
Error message
Connection string not configured for {featureName}. Either configure the feature directly or provide shared settings via the combined persistence feature. What it means
PersistenceShellFeatureBase resolves the connection string at feature configuration time as: feature-specific connection string, then SharedPersistenceSettings.ConnectionString, else it throws. This guards against a DbContext being registered with no way to connect. The message names the concrete feature type so you know which feature lacked configuration.
Solutions
- Configure the shared connection string once via the combined EF Core persistence feature (SharedPersistenceSettings.ConnectionString).
- Or configure the individual feature directly: feature.ConfigureFeature(new EfCorePersistenceFeatureOptions { ConnectionString = ... }).
- Pull the value from configuration/environment and assert it's non-empty at startup before building the host.
- If the connection string is environment-specific, ensure appsettings.json/environment variables are loaded in the failing environment.
Example fix
// before
services.AddElsa(elsa => elsa.UseEntityFrameworkCore(ef => ef.UseSqlite()));
// after
services.AddElsa(elsa => elsa.UseEntityFrameworkCore(ef => ef.UseSqlite("Data Source=elsa.db"))); Defensive patterns
Strategy: validation
Validate before calling
var settings = sp.GetService<IOptions<SharedPersistenceSettings>>()?.Value;
var cs = featureConnectionString ?? settings?.ConnectionString;
if (string.IsNullOrWhiteSpace(cs))
throw new InvalidOperationException(
"No connection string configured for EF Core persistence. Set the feature options or SharedPersistenceSettings.ConnectionString."); Type guard
bool HasPersistenceConnectionString(string? featureCs, SharedPersistenceSettings? shared) =>
!string.IsNullOrWhiteSpace(featureCs) || !string.IsNullOrWhiteSpace(shared?.ConnectionString); Prevention
- Configure connection strings centrally via the combined persistence feature instead of per-feature.
- Validate configuration at startup (fail fast in Program.cs) before the host builds.
- Keep connection strings in appsettings/environment per environment and assert non-empty in CI.
When it happens
Trigger: Registering an EF Core persistence feature (e.g. Runflows/Management/Runtime EF Core persistence features) without calling its ConfigureFeature with a connection string, and without setting ElsaOptions/SharedPersistenceSettings.ConnectionString via the combined persistence feature.
Common situations: Migrating from SQLite/other modules to EF Core persistence and forgetting connection strings; only some features configured directly while the combined shared persistence feature is absent; reading the connection string from environment/config that is empty in a given environment (CI, container); calling Add EF persistence features in the wrong order so shared settings aren't registered.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Provider ' ' is not supported.
- 23505
- Unable to save data
- Register with configured before calling , or call with a…
- The console log provider registration is invalid.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/f0c27dd5ee83bd20.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Persistence.EFCore.Common/PersistenceShellFeatureBase.cs:67
protected virtual Action<IServiceProvider, DbContextOptionsBuilder> DbContextOptionsBuilder { get; set; } = (_, _) => { };
public void ConfigureServices(IServiceCollection services)
{
// Capture feature-specific settings
var featureConnectionString = ConnectionString;
var featureDbContextOptions = DbContextOptions;
var featureUseContextPooling = UseContextPooling;
var featureRunMigrations = RunMigrations;
var featureDbContextFactoryLifetime = DbContextFactoryLifetime;
// Resolve effective settings at runtime, falling back to shared settings
Action<IServiceProvider, DbContextOptionsBuilder> setup = (sp, opts) =>
{
var sharedSettings = sp.GetService<IOptions<SharedPersistenceSettings>>()?.Value;
var connectionString = featureConnectionString
?? sharedSettings?.ConnectionString
?? throw new InvalidOperationException(
$"Connection string not configured for {GetType().Name}. " +
$"Either configure the feature directly or provide shared settings via the combined persistence feature.");
var dbContextOptions = featureDbContextOptions ?? sharedSettings?.DbContextOptions;
opts.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
// Configure the database provider
var migrationsAssembly = GetMigrationsAssembly();
ConfigureProvider(opts, migrationsAssembly, connectionString, dbContextOptions);
// Allow derived classes to further configure
DbContextOptionsBuilder(sp, opts);
};
// Resolve pooling and lifetime settings with fallback
// Note: These are resolved at configuration time, not runtime, but they'll use defaults if not set
var useContextPooling = featureUseContextPooling ?? false;View on GitHub (pinned to fe9217bdfa)