elsa-workflows/elsa-core · error · InvalidOperationException
Adapter ' ' has an invalid settings migration from version…
Error message
Adapter '{adapterType}' has an invalid settings migration from version {version} to {migration.ToVersion}. What it means
Each registered migration must move the version strictly forward (ToVersion > FromVersion) and never beyond the adapter's current version. MigrateAsync throws this when a migration's ToVersion violates either invariant, protecting the loop from non-progress or overshoot.
Solutions
- Fix the migration's ToVersion so it is greater than FromVersion and <= the adapter's current SettingsVersion.
- Remove or gate migrations targeting versions newer than the deployed adapter.
- Add a startup validation that walks each adapter's migration chain and checks monotonicity.
Example fix
// before
new AdapterSettingsMigration("my-adapter", fromVersion: 3, toVersion: 3, ...)
// after
new AdapterSettingsMigration("my-adapter", fromVersion: 3, toVersion: 4, ...) Defensive patterns
Strategy: validation
Validate before calling
if (m.ToVersion <= m.FromVersion || m.ToVersion > currentVersion)
throw new InvalidOperationException($"Invalid migration {m.FromVersion}->{m.ToVersion} for {m.AdapterType}"); Try / catch
try { await service.MigrateAsync(type, v, settings); }
catch (InvalidOperationException ex) when (ex.Message.Contains("invalid settings migration"))
{ /* fix migration registration and redeploy */ } Prevention
- Unit-test each migration's version invariants
- Don't ship migrations for unreleased adapter versions
- Use constants for version numbers to avoid off-by-one
When it happens
Trigger: An IAdapterSettingsMigration registered with ToVersion <= FromVersion (backwards or same-version), or ToVersion greater than adapter.Describe().SettingsVersion (e.g. adapter downgraded but migrations not updated).
Common situations: Copy-paste mistakes in migration definitions; declaring migrations for a future adapter version that isn't deployed yet; off-by-one in version constants.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Settings version is not compatible with adapter ' ' version…
- Adapter ' ' does not provide a settings migration from…
- OpenID Connect settings must be an object.
- The adapter type ' ' is not installed or deployment-allowed.
- Adapter ' ' settings migration contains a cycle.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/ead5ae0cb537fe35.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.ExternalAuthentication/Services/AdapterSettingsMigrationService.cs:42
cancellationToken.ThrowIfCancellationRequested();
if (!adapters.TryGet(adapterType, out var adapter))
throw new InvalidOperationException($"The adapter type '{adapterType}' is not installed or deployment-allowed.");
var currentVersion = adapter.Describe().SettingsVersion;
if (settingsVersion <= 0 || settingsVersion > currentVersion)
throw new InvalidOperationException($"Settings version {settingsVersion} is not compatible with adapter '{adapterType}' version {currentVersion}.");
if (settingsVersion == currentVersion)
return new(currentVersion, settings.Clone(), false);
var migrated = settings.Clone();
var version = settingsVersion;
var stepCount = 0;
while (version < currentVersion)
{
if (!_migrations.TryGetValue((adapterType, version), out var migration))
throw new InvalidOperationException($"Adapter '{adapterType}' does not provide a settings migration from version {version}.");
if (migration.ToVersion <= version || migration.ToVersion > currentVersion)
throw new InvalidOperationException($"Adapter '{adapterType}' has an invalid settings migration from version {version} to {migration.ToVersion}.");
if (++stepCount > 64)
throw new InvalidOperationException($"Adapter '{adapterType}' settings migration contains a cycle.");
migrated = (await migration.MigrateAsync(migrated, cancellationToken)).Clone();
version = migration.ToVersion;
}
return new(version, migrated, true);
}
private static IReadOnlyDictionary<(string AdapterType, int FromVersion), IAdapterSettingsMigration> BuildMigrationIndex(
IEnumerable<IAdapterSettingsMigration> migrations)
{
var result = new Dictionary<(string AdapterType, int FromVersion), IAdapterSettingsMigration>();
foreach (var migration in migrations)
{
if (string.IsNullOrWhiteSpace(migration.AdapterType) || migration.FromVersion <= 0)
throw new InvalidOperationException("Adapter settings migrations must define an adapter type and a positive source version.");View on GitHub (pinned to fe9217bdfa)